F#中Scala的Seq.Span等效于什么? [英] What is the equivalent of Scala's Seq.Span in F#?

查看:109
本文介绍了F#中Scala的Seq.Span等效于什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

引用根据谓词将此可迭代集合拆分为前缀/后缀对.

Splits this iterable collection into a prefix/suffix pair according to a predicate.

请注意:只要对谓词p的求值没有引起任何副作用,c span p等效于(但可能比p更有效),c则p等于c dropW而p却无效.

Note: c span p is equivalent to (but possibly more efficient than) (c takeWhile p, c dropWhile p), provided the evaluation of the predicate p does not cause any side-effects.

注意:对于不同的运行,可能会返回不同的结果,除非订购了基础的收集类型.

Note: might return different results for different runs, unless the underlying collection type is ordered.

  • p-测试谓词
  • 返回-一对,其元素均满足p的此可迭代集合的最长前缀,以及此可迭代集合的其余前缀.
  • 定义类-IterableOps→IterableOnceOps
  • 注意-重用:调用此方法后,应丢弃被调用的迭代器,而仅使用返回的迭代器.使用旧的迭代器是不确定的,可能会发生更改,并且可能还会导致新的迭代器发生更改.

查看 F#文档对于Seq,我看不到任何等效内容.

When looking at the F# documentation for Seq I don't see any equivalent.

groupBy,partition,splitAt,它们都不符合我要执行的操作.就像同时执行一个takeWhile和skipWhile一样,但是不需要两个迭代,您只需要一个迭代即可使函数返回一个元组(takeWhile,skipWhile).

groupBy, partition, splitAt, none of them match what I'm trying to do. It's like doing a takeWhile and skipWhile at the same time but instead of needing two iterations you only need one where the function would return a tuple of (takeWhile, skipWhile).

输出应符合以下功能

module List
let span (predicate: 'a -> bool) (list: 'a list): ('a list * 'a list) =
    (list |> List.takeWhile predicate, list |> List.skipWhile predicate)

但是由于我的序列可能是无限的,所以只需要迭代一次.

But only need one iteration since my sequence may be infinite.

[1;2;3;4] |> List.span (fun i -> i % 2 = 1) => ([1], [2;3;4])

推荐答案

这是我想出的,它不是一个很好的答案,因为它需要您急切地遍历第一个,所以如果您返回true足够长的时间,您就可以将吹没有记忆.我将让问题再开放几天,如果我没有找到更好的答案,我会标记为这个问题.再一次,我真的希望有一个更好的答案,该答案在任何情况下都可以完全适用于无限序列.

This is what I've come up with, it's not a great answer because it requires you eagerly iterate through the first one so if you return true long enough you will blow without of memory. I will leave the question open for a few more days and if I don't see a better answer I will mark this one. Again I would really like a better answer that completely works with an infinite sequence in any situation.

module Seq

let span (predicate: 'a -> bool) (sequence: 'a seq): ('a seq * 'a seq) =
    let enumerator = sequence.GetEnumerator()
    let isNotDone = ref (enumerator.MoveNext())
    let first = seq {
        let e = enumerator
        if !isNotDone then
            while (!isNotDone && predicate e.Current) do
                yield enumerator.Current
                isNotDone := e.MoveNext() }
    let second = seq {
        use e = enumerator
        if !isNotDone then
            yield e.Current
            while e.MoveNext() do
                yield e.Current }
    let eagerFirst = List.toSeq (Seq.toList first)
    (eagerFirst, second)

这篇关于F#中Scala的Seq.Span等效于什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆