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

时间:2015-03-23 17:55:21

标签: scala scala-collections

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

myoptionList.filter(_.isDefined).map(_.get)

这需要两次迭代时间,有没有更好的方法呢?

3 个答案:

答案 0 :(得分:5)

你有几个选择。最简单的可能是flatten。由于Option可以隐式转换为Iterable,因此flatten Options的列表与列表列表的方式非常相似:

myOptionList.flatten

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

myOptionList.flatMap(x => x)
myOptionList.flatMap(identity(_))
myOptionList.flatMap(Option.option2Iterable)
myOptionList.flatMap[Int,List[Int]](identity)

您也可以使用collectcollectPartialFunction为参数。如果找到匹配项,则根据函数映射该值。否则它被过滤掉了。所以在这里,您可以仅匹配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
}

我还想提一下,一般来说,如果你有一个复杂的逻辑,在列表上执行多个操作,但你不想多次遍历列表,你可以使用view

myOptionList.view.filter(_.isDefined).map(_.get) //Will only traverse list once!

答案 1 :(得分:2)

假设某myOptionList List[Option[T]]T,您可以使用flatten

val values = myOptionList.flatten

答案 2 :(得分:0)

只需使用collect

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

collect只需一步即可映射和过滤。