2011-01-19 41 views
68

Estoy empezando a explorar Scala, y una de las cosas que me intriga es el tipo Option y la promesa de poder eliminar null errores relacionados .Cómo transformar la colección Scala de la Opción [X] a la colección de X

Sin embargo no he podido encontrar la manera de transformar una lista (u otra colección) de, por ejemplo, Option[String], a una colección de String (obviamente, el filtrado de los valores que estén None).

En otras palabras, ¿cómo puedo obtener de esto:

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

... a esto:

List[Int] = List(1) 

estoy usando Scala 2.8 si eso tiene algún impacto en la respuesta.

Respuesta

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

Embarrassingly simple (como esperaba que fuera)! Gracias. – npad

+7

Sin embargo, vale la pena señalar que solo funciona porque hay una conversión implícita de la Opción [A] a GenTraversableOnce [A] – kosii

+0

@kosii Parece (al menos en Scala 2.11.6) que la conversión es de la Opción [A] a Iterable [A] –

53

Para fines educativos, que le gustaría algunas alternativas:

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, se puede realizar una operación ligeramente diferente llamado sequence, que devuelve 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)) 
Cuestiones relacionadas