Як перетворити колекцію Scala Option [X] на колекцію X


76

Я починаю досліджувати Scala, і одна з речей, яка мене заінтригувала, - це Optionтип і обіцянка можливості усунути nullпов'язані з цим помилки.

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

Іншими словами, як я можу отримати з цього:

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

... до цього:

List[Int] = List(1)

Я використовую Scala 2.8, якщо це впливає на відповідь.

Відповіді:


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

9
Варто зазначити, однак, що це працює лише тому, що існує неявне перетворення з Option [A] на GenTraversableOnce [A]
kosii

1
@kosii Схоже (принаймні в Scala 2.11.6) перетворення здійснюється з Option [A] в Iterable [A]
Брайан Гордон

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))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.