Scala:筛选选项集合
假设我有一个函数,用于检查某个操作是否适用于a的实例,如果适用,则返回B的实例或无: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) ) //
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
,这可能很难作为部分函数编写。