Scala 中映射和过滤空值的组合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8938916/
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
Combination of map and filter nulls out in Scala
提问by Timo Westk?mper
Is it possible to express the following code in such a way that the map and null skipping is expressed in one call?
是否有可能以这样一种方式表达以下代码,即在一次调用中表达映射和空跳过?
list.map(_.accept(this, arg).asInstanceOf[T]).filter(_ != null)
回答by Debilski
list flatMap { i => Option(i.accept(this, arg).asInstanceOf[T]) }
or alternatively, if you like, (though this will be converted more or less to your original expression)
或者,如果您愿意,(尽管这会或多或少地转换为您的原始表达式)
for {
item <- list
itemConverted = item.accept(this, arg).asInstanceOf[T]
itemNonNull = itemConverted if itemConverted != 0
} yield itemNonNull
Using collectwould be possible but it would likely call accepttwice on most arguments because of the isDefinedAttest of the partial function:
使用collect是可能的,但accept由于isDefinedAt偏函数的测试,它可能会在大多数参数上调用两次:
list collect {
case i if i.accept(this, arg).asInstanceOf[T] != null => i.accept(this, arg).asInstanceOf[T]
}
One would need to use some memoising (or smart extractors) to avoid this.
人们需要使用一些记忆(或智能提取器)来避免这种情况。
回答by Dan Burton
If you are concerned about performance, you can add .view
如果您担心性能,可以添加 .view
list.view.map(_.accept(this, arg).asInstanceOf[T]).filter(_ != null)
viewcauses the traversal to become lazy, thus the mapand filterwill be performed in one pass over the list rather than two separate passes.
view导致遍历变得懒惰,因此map和filter将在一次遍历列表而不是两次单独的遍历中执行。
If you are concerned about reusing this pattern, you can define your own helper function:
如果您担心重用此模式,您可以定义自己的辅助函数:
def mapNN[A,B](list: List[A])(f: A => B) = {
list.view.map(f(_)).filter(_ != null)
}
mapNN(list)(_.accept(this, arg).asInstanceOf[T])
Testing...
测试...
> mapNN(List(1,2,3))(x => if (x%2==0) x else null).toList
res7: List[Any] = List(2)

