2011-01-19 7 views
68

Sto iniziando ad esplorare Scala, e una delle cose che mi affascina è il tipo Option e la promessa di poter eliminare gli errori relativi a null .Come trasformare la raccolta Scala di Option [X] nella raccolta di X

Tuttavia non sono stato in grado di capire come trasformare una lista (o altra raccolta), per esempio, Option[String], ad una raccolta di String (ovviamente filtrare tutti i valori che sono None).

In altre parole, come faccio ad ottenere da questo:

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

... a questo:

List[Int] = List(1) 

sto usando Scala 2.8 se questo abbia alcun impatto sulla risposta.

risposta

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

Semplicemente imbarazzante (come speravo sarebbe)! Grazie. – npad

+7

Vale la pena notare, però, che funziona solo perché c'è una conversione implicita da Opzione [A] a GenTraversableOnce [A] – kosii

+0

@kosii Sembra (in Scala 2.11.6 almeno) la conversione va da Opzione [A] a iterable [A] –

53

per scopi educativi, come si potrebbe alcune alternative:

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) 

Con Scalaz, è possibile eseguire un'operazione leggermente diversa chiamato sequence, che restituisce 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)) 
Problemi correlati