检查"isDefined"并一起映射到"get"

Omi*_*mid 3 scala scala-collections

如何更有效地执行以下操作:

myoptionList.filter(_.isDefined).map(_.get)
Run Code Online (Sandbox Code Playgroud)

这需要两次迭代时间,有没有更好的方法来做到这一点?

Ben*_*ich 5

你有几个选择.最简单的可能是flatten.由于Option可以隐式转换为Iterable,您可以flatten使用与列表列表Options大致相同的列表:

myOptionList.flatten
Run Code Online (Sandbox Code Playgroud)

您也可以使用flatMap相同的方式.以下是一些选项:

myOptionList.flatMap(x => x)
myOptionList.flatMap(identity(_))
myOptionList.flatMap(Option.option2Iterable)
myOptionList.flatMap[Int,List[Int]](identity)
Run Code Online (Sandbox Code Playgroud)

你也可以使用collect. collect以一个PartialFunction参数为例.如果找到匹配项,则根据函数映射该值.否则它被过滤掉了.所以在这里,你可以只匹配Some(x)并映射到x(以便所有Nones都被过滤掉).此选项是最常用的,如果您愿意,将允许您应用更精细的逻辑.

myOptionList.collect { case Some(x) => x }

//Example of more complex logic:
myOptionList.collect {
    case Some(x) if x % 2 == 0 => x / 2
}
Run Code Online (Sandbox Code Playgroud)

我还想提一下,一般情况下,当你有一个复杂的逻辑,在列表上进行多个操作,但你不想多次遍历列表时,你可以使用view:

myOptionList.view.filter(_.isDefined).map(_.get) //Will only traverse list once!
Run Code Online (Sandbox Code Playgroud)