有没有一种方法可以在不同时执行以下两种方法的情况下执行以下操作:find
和map
?
val l = 0 to 3
l.find(_ * 33 % 2 == 0).map(_ * 33) // returns Some(66)
答案 0 :(得分:27)
如何使用收藏?
// Returns List(66)
List(1, 2, 3) collect { case i if (i * 33 % 2 == 0) => i * 33 }
然而,这将返回所有匹配,而不仅仅是第一个匹配。
基于Scala 2.9,答案会更好:
// Returns Some(66)
List(1, 2, 3) collectFirst { case i if (i * 33 % 2 == 0) => i * 33 }
在评论中建议添加head
以获得Scala 2.8版本的解决方案并不是非常有效,我担心。也许在那种情况下我会坚持你自己的代码。在任何情况下,为了确保它返回一个选项,您不应该致电head
,而是headOption
。
// Returns Some(66)
List(1, 2, 3) collect { case i if (i * 33 % 2 == 0) => i * 33 } headOption
答案 1 :(得分:18)
如果您不想多次执行map()
操作(例如,如果这是一次昂贵的数据库查询),您可以这样做:
l.view.map(_ * 33).find(_ % 2 == 0)
view
使得集合变得懒惰,因此map()
操作的数量最小化。
答案 2 :(得分:6)
findMap
了!
/**
* Finds the first element in the list that satisfies the partial function, then
* maps it through the function.
*/
def findMap[A,B](in: Traversable[A])(f: PartialFunction[A,B]): Option[B] = {
in.find(f.isDefinedAt(_)).map(f(_))
}
请注意,与接受的答案不同,但与其中一条评论中提到的collectFirst
方法不同,这个人一找到匹配的元素就会停止。
答案 3 :(得分:-1)
这可以做到,但如果你说出你真正想要实现的目标会更容易:
l.flatMap(n => if (n * 33 % 2 == 0) Some(n * 33) else None).headOption