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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5479227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:55:56  来源:igfitidea点击:

How to find a matching element in a list and map it in as an Scala API method?

scalascala-2.8

提问by agilefall

Is there a method to do the following without doing both methods: findand map?

有没有一种方法可以在不执行这两种方法的情况下执行以下操作:findmap

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

回答by Wilfred Springer

How about using collect?

使用收集怎么样?

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

However that will return allmatches and not just the first one.

但是,这将返回所有匹配项,而不仅仅是第一个匹配项。

The better answer would have been, based on Scala 2.9:

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

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

The solution suggested in the comments to append a headto get a Scala 2.8 version of that is not very efficient, I'm afraid. Perhaps in that case I would stick to your own code. In any case, in order to make sure it returns an option, you should not call head, but headOption.

head恐怕在评论中建议的解决方案附加 a以获得 Scala 2.8 版本的效率不是很高。也许在那种情况下,我会坚持使用您自己的代码。在任何情况下,为了确保它返回一个选项,你不应该调用head, 而是headOption

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

回答by Garrett Hall

If you don't want to do your map()operation multiple times (for instance if it's an expensive DB lookup) you can do this:

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

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

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

The viewmakes the collection lazy, so the number of map()operations is minimized.

view使得集合变得懒惰,因此map()操作的数量被最小化。

回答by Alex Cruise

Hey look, it's my little buddy findMapagain!

嘿看,又是我的小伙伴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(_))
}

Note that, unlike in the accepted answer, but like the collectFirstmethod mentioned in one of its comments, this guy stops as soon as he finds a matching element.

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

回答by thoredge

This can do it, but it would be easier if you tell what you're really trying to achieve:

这可以做到,但如果你说出你真正想要实现的目标会更容易:

l.flatMap(n => if (n * 33 % 2 == 0) Some(n * 33) else None).headOption