假设我有一个函数检查某个操作是否适用于A的实例,如果是,则返回B或None的实例:
def checker[A,B]( a: A ) : Option[B] = ...
现在我想形成一个包含B的所有有效实例的新集合,删除None值。以下代码似乎可以完成这项工作,但肯定有更好的方法:
val as = List[A]( a1, a2, a3, ... )
val bs =
as
.map( (a) => checker(a) ) // List[A] => List[Option[B]]
.filter( _.isDefined ) // List[Option[B]] => List[Option[B]]
.map( _.get ) // List[Option[B]] => List[B]
谢谢!
答案 0 :(得分:25)
这应该这样做:
val bs = as.flatMap(checker)
答案 1 :(得分:11)
上面的答案是正确的,但如果您可以重写checker
,建议您使用PartialFunction
和collect
。 PartialFunction是类型A => B的函数,不需要为A的所有值定义。这是一个简单的例子:
scala> List(1, 2, 3, 4, "5") collect {case x : Int => x + 42}
res1: List[Int] = List(43, 44, 45, 46)
collect
将PartialFunction的实例作为参数,并将其应用于集合的所有元素。在我们的例子中,该函数仅针对Ints
定义,并且"5"
被过滤。因此,collect
是map
和filter
的组合,这正是您的情况。