如何在列表中查找匹配元素并将其作为Scala API方法映射?

agi*_*all 20 scala scala-2.8

有没有做到以下几点没有做这两种方法的方法:findmap

val l = 0 to 3
l.find(_ * 33 % 2 == 0).map(_ * 33) // returns Some(66)
Run Code Online (Sandbox Code Playgroud)

Wil*_*ger 28

如何使用收集?

// Returns List(66)
List(1, 2, 3) collect { case i if (i * 33 % 2 == 0) => i * 33 }
Run Code Online (Sandbox Code Playgroud)

然而,这将返回所有匹配,而不仅仅是第一个.

基于Scala 2.9,更好的答案是:

// Returns Some(66)
List(1, 2, 3) collectFirst { case i if (i * 33 % 2 == 0) => i * 33 }
Run Code Online (Sandbox Code Playgroud)

在评论中建议附加一个head获得Scala 2.8版本的解决方案效率不高,我担心.也许在那种情况下我会坚持你自己的代码.在任何情况下,为了确保它返回一个选项,你不应该打电话head,但是headOption.

// Returns Some(66)
List(1, 2, 3) collect { case i if (i * 33 % 2 == 0) => i * 33 } headOption
Run Code Online (Sandbox Code Playgroud)

  • Scala 2.9增加了一个`collectFirst`方法.否则,正如Daniel的评论所暗示的那样,除了`collect`之外,你还需要使用`headOption`来获得与原始示例相同的类型和行为. (3认同)

Gar*_*all 19

如果您不想map()多次执行操作(例如,如果这是一个昂贵的数据库查找),您可以这样做:

l.view.map(_ * 33).find(_ % 2 == 0)

view将集合懒惰,所以数量map()操作最小化.

  • 我认为这是这个问题最正确的答案.在大多数情况下,其他的都没用,因为操作必须执行两次. (2认同)

Ale*_*ise 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(_))
}
Run Code Online (Sandbox Code Playgroud)

请注意,与接受的答案不同,但是就像collectFirst其中一条评论中提到的方法一样,这个人一找到匹配元素就会停止.