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

时间:2016-02-03 12:15:40

标签: scala functional-programming

我刚刚开始学习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});

在试验中我找到了

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

给我回报

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

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

无限奔跑。

2 个答案:

答案 0 :(得分:15)

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

filter必须评估整个流。

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

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

答案 1 :(得分:10)

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

filter

  

返回满足谓词p

所有元素

takeWhile

  

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

E.g。

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

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

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