Comment transformer la collection Scala de l'option [X] à la collecte de X
-
12-10-2019 - |
Question
Je commence à explorer Scala, et l'une des choses que je suis intrigué par est le type de Option
et la promesse d'être en mesure d'éliminer les erreurs liées à null
.
Cependant, je n'ai pas été en mesure de travailler sur la façon de transformer une liste (ou toute autre collection), disons, Option[String]
, à une collection de String
(filtrage évidemment sur toutes les valeurs qui sont None
).
En d'autres termes, comment puis-je obtenir de ceci:
List[Option[Int]] = List(Some(1))
... à ceci:
List[Int] = List(1)
J'utilise Scala 2.8 si cela a un impact sur la réponse.
La solution
val list1 = List(Some(1), None, Some(2))
val list2 = list1.flatten // will be: List(1,2)
Autres conseils
Pour des fins éducatives, vous pourriez aimer des alternatives:
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)
Avec Scalaz, vous pouvez effectuer une opération légèrement différente appelée sequence
, que les rendements 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))