如何将Option [X]的Scala集合转换为X的集合


76

我开始探索Scala,而我感兴趣的事情Option之一就是能够消除null相关错误的类型和前景。

但是,我还无法弄清楚如何将的列表(或其他集合)转换Option[String]为的集合String(显然会过滤掉的任何值None)。

换句话说,我如何从中得到:

List[Option[Int]] = List(Some(1))

...对此:

List[Int] = List(1)

我正在使用Scala 2.8,如果这对答案有影响。

Answers:


134
val list1 = List(Some(1), None, Some(2))
val list2 = list1.flatten // will be: List(1,2)

9
值得一提的是,它仅能从Option [A]隐式转换为GenTraversableOnce [A]
kosii,2015年

1
@kosii看起来(至少在Scala 2.11.6中)是从Option [A]到Iterable [A]的转换
Brian Gordon

58

出于教育目的,您可能需要一些替代方法:

scala> val list1 = List(Some(1), None, Some(2))
list1: List[Option[Int]] = List(Some(1), None, Some(2))

scala> list1 flatten
res0: List[Int] = List(1, 2)

// Expanded to show the implicit parameter
scala> list1.flatten(Option.option2Iterable)
res1: List[Int] = List(1, 2)

scala> list1 flatMap (x => x)
res2: List[Int] = List(1, 2)

scala> list1 flatMap Option.option2Iterable
res3: List[Int] = List(1, 2)

// collect is a simultaneous map + filter
scala> list1 collect { case Some(x) => x }
res4: List[Int] = List(1, 2)

使用Scalaz,您可以执行一个稍微不同的操作sequence,该操作返回Option[List[Int]]

scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._

scala> val list1: List[Option[Int]] = List(Some(1), None, Some(2)) 
list1: List[Option[Int]] = List(Some(1), None, Some(2))

scala> list1.sequence                                              
res1: Option[List[Int]] = None

scala> val list2: List[Option[Int]] = List(Some(1), Some(2))         
list2: List[Option[Int]] = List(Some(1), Some(2))

scala> list2.sequence
res2: Option[List[Int]] = Some(List(1, 2))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.