当以后应用像map,flatmap等函数时,使用filter而不是filter是否总是更高效?withFilter而不是过滤器
为什么只支持map,flatmap和foreach? (像forall这样的预期功能也存在)
当以后应用像map,flatmap等函数时,使用filter而不是filter是否总是更高效?withFilter而不是过滤器
为什么只支持map,flatmap和foreach? (像forall这样的预期功能也存在)
注:区别
c filter p
和c withFilter p
之间的区别在于前者 创建了一个新的集合,而后者仅限制了的域后续map
,flatMap
,foreach
和withFilter
操作。
所以filter
将原来的收集和产生一个新的集合,但withFilter
将非严格(即懒洋洋地)到后来map
/flatMap
/withFilter
调用传递未过滤的值,节省通过(过滤第二遍)集合。因此,在传递给这些后续的方法调用时它会更高效。
实际上,withFilter
是专门设计用于处理这些方法的链,这是理解被去除的东西。此方法不需要其他方法(如forall
/exists
),因此它们尚未被添加到FilterMonadic
返回类型withFilter
。
作为一种解决方法,您只能使用map
和flatMap
来实现其他功能。
而且,这种优化是小集合没用......
使用对产量可周围的工作,例如:
for {
e <- col;
if e isNotEmpty
} yield e.get(0)
此外,the excellent answer of Shadowlands,我想带一个直观的例子,filter
和withFilter
之间的区别。
让我们看看下面的代码
val list = List(1, 2, 3)
var go = true
val result = for(i <- list; if(go)) yield {
go = false
i
}
大多数人期待result
等于List(1)
。这是自斯卡拉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
}
}
使用filter
的result
值将是相当不同的:List(1, 2, 3)
。事实上,我们使go
标志false
对过滤器没有影响,因为过滤器已经完成。再次,在Scala 2.8中,这个问题使用withFilter
来解决。当使用withFilter
时,每次在map
方法内访问元素时都会评估条件。
参考: - 第120页,斯卡拉在行动(包括斯卡拉2.10),曼宁出版物,Milanjan Raychaudhuri - Odersky's thoughts about for-comprehension translation
希望他们仍然增加这些方法的一些日子。 – Kigyo
@Kigyo我不认为你应该自己使用Filter(除了隐含在for表达式之外)。如果你想要地图/过滤器是懒惰的,请使用'view'。 –
我明白了。 'view'和'withFilter'之间的确切区别是什么?为什么不是用于'for-loops'的视图? – Kigyo