Как преобразовать коллекцию Scala Option[X] в коллекцию X

Я начинаю изучать Scala, и одна из вещей, которые меня заинтриговали, — это тип Option и возможность устранения ошибок, связанных с null.

Однако я не смог понять, как преобразовать список (или другую коллекцию), скажем, Option[String], в коллекцию String (очевидно, отфильтровывая любые значения, которые равны None).

Другими словами, как я могу получить от этого:

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

... к этому:

List[Int] = List(1)

Я использую Scala 2.8, если это как-то повлияет на ответ.


person npad    schedule 19.01.2011    source источник


Ответы (2)


В образовательных целях вам могут понравиться некоторые альтернативы:

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))
person retronym    schedule 19.01.2011

person    schedule
comment
Однако стоит отметить, что это работает только потому, что существует неявное преобразование из Option[A] в GenTraversableOnce[A] - person kosii; 15.04.2015
comment
@kosii Похоже (по крайней мере, в Scala 2.11.6) преобразование из Option[A] в Iterable[A] - person Brian Gordon; 29.04.2015