是否可以通过一次调用表示map和null跳过来表达以下代码?
list.map(_.accept(this, arg).asInstanceOf[T]).filter(_ != null)
Run Code Online (Sandbox Code Playgroud)
Deb*_*ski 11
list flatMap { i => Option(i.accept(this, arg).asInstanceOf[T]) }
Run Code Online (Sandbox Code Playgroud)
或者,如果您愿意,(尽管这会或多或少地转换为您的原始表达)
for {
item <- list
itemConverted = item.accept(this, arg).asInstanceOf[T]
itemNonNull = itemConverted if itemConverted != 0
} yield itemNonNull
Run Code Online (Sandbox Code Playgroud)
使用collect是可能的,但accept由于isDefinedAt部分函数的测试,它可能会在大多数参数上调用两次:
list collect {
case i if i.accept(this, arg).asInstanceOf[T] != null => i.accept(this, arg).asInstanceOf[T]
}
Run Code Online (Sandbox Code Playgroud)
人们需要使用一些记忆(或智能提取器)来避免这种情况.
如果您担心性能,可以添加 .view
list.view.map(_.accept(this, arg).asInstanceOf[T]).filter(_ != null)
Run Code Online (Sandbox Code Playgroud)
view导致遍历变得懒惰,因此map并且filter将在列表中的一次传递中执行,而不是两次单独的传递.
如果您担心重用此模式,可以定义自己的辅助函数:
def mapNN[A,B](list: List[A])(f: A => B) = {
list.view.map(f(_)).filter(_ != null)
}
mapNN(list)(_.accept(this, arg).asInstanceOf[T])
Run Code Online (Sandbox Code Playgroud)
测试...
> mapNN(List(1,2,3))(x => if (x%2==0) x else null).toList
res7: List[Any] = List(2)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15926 次 |
| 最近记录: |