So transformieren Sie die Scala-Sammlung von Option [X] in die Sammlung von X.

75

Ich fange an, Scala zu erkunden, und eines der Dinge, die mich faszinieren, ist der OptionTyp und das Versprechen, nullverwandte Fehler beseitigen zu können.

Ich war jedoch nicht in der Lage herauszufinden, wie eine Liste (oder eine andere Sammlung) von beispielsweise Option[String]in eine Sammlung von String(offensichtlich Herausfiltern von Werten None) umgewandelt werden kann.

Mit anderen Worten, wie komme ich daraus:

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

... dazu:

List[Int] = List(1)

Ich verwende Scala 2.8, wenn dies Auswirkungen auf die Antwort hat.

npad
quelle

Antworten:

132
val list1 = List(Some(1), None, Some(2))
val list2 = list1.flatten // will be: List(1,2)
Madoc
quelle
9
Es ist jedoch erwähnenswert, dass es nur funktioniert, weil es eine implizite Konvertierung von Option [A] zu GenTraversableOnce [A] gibt
kosii
1
@kosii Sieht aus wie (zumindest in Scala 2.11.6) die Konvertierung von Option [A] zu Iterable [A]
Brian Gordon
58

Zu Bildungszwecken könnten Ihnen einige Alternativen gefallen:

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)

Mit Scalaz können Sie eine etwas andere Operation ausführen sequence, die zurückgegeben wird 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))
Retronym
quelle