Scala:流上的 filter 和 takeWhile 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35176819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 07:59:57  来源:igfitidea点击:

Scala: What is the difference between filter and takeWhile on a stream?

scalafunctional-programming

提问by AbrahamDaniel

I just started to learn Scala, and I'm confused between the filter and takeWhile while working on streams.

我刚开始学习 Scala,在处理流时,我对 filter 和 takeWhile 感到困惑。

I came across this program to generate prime numbers, which uses both takeWhile and filter on a stream.

我遇到了这个程序来生成素数,它在流上同时使用 takeWhile 和 filter。

lazy val ps: Stream[Int] = 2 #:: Stream.from(3).filter(i => 
             ps.takeWhile{j => j * j <= i}.forall{ k => i % k > 0});

While experimenting i found

在试验时我发现

Stream.from(1).takeWhile(_ < 10).toList

returns me

还我

List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

while

尽管

 Stream.from(1).filter(_ < 10).toList

runs infinitely.

无限运行。

回答by PawelN

takeWhile()stop evaluation immediately after condition is not met.

takeWhile()不满足条件后立即停止评估。

filterhave to evaluate the whole Stream.

filter必须评估整个流。

I suggest You to analyze this two function in below code:

我建议你在下面的代码中分析这两个函数:

https://github.com/fpinscala/fpinscala/blob/master/answers/src/main/scala/fpinscala/laziness/Stream.scala

https://github.com/fpinscala/fpinscala/blob/master/answers/src/main/scala/fpinscala/laziness/Stream.scala

回答by Alexey Romanov

The difference isn't stream-specific, but the same for all collections extending GenTraversableLike:

差异不是特定于流的,但对于所有扩展的集合都是相同的GenTraversableLike

filter

filter

Returns all the elementsthat satisfy the predicate p

返回满足谓词的所有元素p

takeWhile

takeWhile

Returns the longest prefixwhose elements satisfy the predicate p.

返回其元素满足谓词的最长前缀p

E.g.

例如

> List(1, 2, 3, 4).filter(_ % 2 == 1)
List(1, 3)

> List(1, 2, 3, 4).takeWhile(_ % 2 == 1)
List(1)

In particular, Stream.from(1).filter(_ < 10).toListdoesn't finish because it has to check every element of the stream: it doesn't "know" there won't be any elements which satisfy _ < 10after 9 (and actually, there are, thanks to wraparound).

特别是,Stream.from(1).filter(_ < 10).toList没有完成,因为它必须检查流的每个元素:它不“知道”_ < 10在 9 之后不会有任何满足的元素(实际上,由于环绕,有)。