Scala:过滤器和takeWhile在流上有什么区别?

Abr*_*iel 7 functional-programming scala

我刚开始学习Scala,在使用流时我在过滤器和takeWhile之间感到困惑.

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

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

在试验时我发现了

Stream.from(1).takeWhile(_ < 10).toList
Run Code Online (Sandbox Code Playgroud)

回报我

List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
Run Code Online (Sandbox Code Playgroud)

 Stream.from(1).filter(_ < 10).toList
Run Code Online (Sandbox Code Playgroud)

无限地奔跑.

Paw*_*elN 15

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

filter 必须评估整个流.

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

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


Ale*_*nov 11

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

filter

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

takeWhile

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

例如

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

> List(1, 2, 3, 4).takeWhile(_ % 2 == 1)
List(1)
Run Code Online (Sandbox Code Playgroud)

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