Scala:筛选选项集合

Scala:筛选选项集合,scala,map,filter,option,Scala,Map,Filter,Option,假设我有一个函数,用于检查某个操作是否适用于a的实例,如果适用,则返回B的实例或无: def checker[A,B]( a: A ) : Option[B] = ... 现在,我想形成一个新集合,其中包含B的所有有效实例,删除None值。下面的代码似乎可以完成这项工作,但肯定有更好的方法: val as = List[A]( a1, a2, a3, ... ) val bs = as .map( (a) => checker(a) ) //

假设我有一个函数,用于检查某个操作是否适用于a的实例,如果适用,则返回B的实例或无:

   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]
谢谢

这应该可以做到:

val bs = as.flatMap(checker)

上面的答案是正确的,但是如果您可以重写
检查器
,我建议您使用
部分功能
收集
。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
的组合,这正是您的情况。

flatMapshit@oxbow_lakes我相信正确的引语是:“这是什么?业余时间?平面地图那狗屎!”这句引语来源于twitter吗?这句引语来自哪里?谁做的?对我不起作用,原因有很多:1。类型推断,2。List#flatMap需要一次GenTraversableOne。正确的方法是.flatMap{a=>checker[a,B](a)},我用
Int
Option[String]
的函数对它进行了测试。最糟糕的情况是,您必须向它添加一些显式类型。
collect
确实是
filter
map
的组合,但它通常不在另一个方向工作(
map
然后
filter
),因为您需要在case语句的保护中定义过滤器。因此,替换OP的最后两条语句(使用
.collect{case Some(x)=>x}
)是很好的,但是如果
检查器
涉及任何一种非平凡的计算来决定是返回
Some
还是返回
None
,这可能很难作为部分函数编写。