如何过滤列表中的“无”[选项] ?

如果我在 Scala 中有一个 List[Option[A]],那么过滤掉 None值的惯用方法是什么?

一种方法是使用以下内容:

val someList: List[Option[String]] = List(Some("Hello"), None, Some("Goodbye"))
someList.filter(_ != None)

还有更“惯用”的方法吗? 这看起来确实很简单。

56421 次浏览

如果你想同时摆脱这些选项,你可以使用 flatten:

scala> someList.flatten
res0: List[String] = List(Hello, Goodbye)

如果希望将结果类型保持为 List[Option[A]],则为 someList.filter(_.isDefined)

cats库也有 flattenOption,它将任何 F[Option[A]]转换成 F[A](其中 F[_]FunctorFilter)

import cats.implicits._


List(Some(1), Some(2), None).flattenOption == List(1, 2)

如果对象的选项列表比字符串更复杂,如下所示:

case class Thing(name: String, number: Int)


val someSequence: Seq[Option[Thing]] = Seq(
Some(Thing("Hello", 1)),
None,
Some(Thing("Goodbye", 2)),
None
)

您可以使用 latMap 来链接内部值的映射:

scala> someSequence.flatMap(_.map(_.name))
val res2: Seq[String] = List(Hello, Goodbye)

但在我看来,“ Nicolas”的上述回答更为清晰,因为你可以这样做:

scala> someSequence.flatten.map(_.name)
val res3: Seq[String] = List(Hello, Goodbye)