问题描述
引用 Scala的文档:
def span(p: (A) => Boolean): (Seq[A], Seq[A])
根据谓词将此可迭代集合拆分为前缀/后缀对.
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等效于什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!