用filter代替filter

在使用filter,flatmap等函数的时候,使用Filter来代替filter,总是更高效的吗?

为什么只支持map,flatmap和foreach? (像forall /期望的function也存在)

从scala文档:

Note: the difference between c filter p and c withFilter p is that the former creates a new collection, whereas the latter only restricts the domain of subsequent map, flatMap, foreach, and withFilter operations. 

因此, filter将采集原始集合并生成一个新的集合,但是withFilter将非严格地(即,懒惰地)将未过滤的值传递给后来的map / flatMap / withFilter调用,并通过(过滤的)集合保存第二遍。 因此,通过这些后续的方法调用将会更高效。

实际上, withFilter是专门为这些方法的链条而devise的,这是一种理解去除的方法。 没有其他的方法(如forall / exists )需要这个,所以它们还没有被添加到FilterMonadicwithFilter返回types中。

除了Shadowlands的出色答案之外,我还想给出一个直观的filterwithFilter

我们来考虑下面的代码

 val list = List(1, 2, 3) var go = true val result = for(i <- list; if(go)) yield { go = false i } 

大多数人期望result等于List(1) 。 从Scala 2.8开始就是这样,因为理解被翻译成了

 val result = list withFilter { case i => go } map { case i => { go = false i } } 

正如你所看到的,翻译将条件转换为对withFilter的调用。 之前的Scala 2.8中,理解被翻译成如下内容:

 val r2 = list filter { case i => go } map { case i => { go = false i } } 

使用filterresult的值会相当不同: List(1, 2, 3) 。 我们将go标志设置为false的事实对filter没有影响,因为filter已经完成。 再一次,在Scala 2.8中,使用withFilter解决了这个问题。 当使用withFilter器时,每次在map方法中访问元素时都会评估条件。

参考 : – 第120页,斯卡拉在行动(涵盖斯卡拉2.10),曼宁出版社,Milanjan Raychaudhuri – Odersky关于理解翻译的想法

用于产量可以是一个工作,例如:

 for { e <- col; if e isNotEmpty } yield e.get(0) 

作为一种解决方法,您可以仅使用mapflatMap来实现其他函数。

而且,这个优化在小集合上是无用的…