Comment aplatir la liste des options à l'aide des fonctions d'ordre supérieur?
Utilisation De Scala 2.7.7:
Si j'ai une liste d'Options, je peux les aplatir à l'aide d'un pour-de la compréhension:
val listOfOptions = List(None, Some("hi"), None)
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)
scala> for (opt <- listOfOptions; string <- opt) yield string
res0: List[java.lang.String] = List(hi)
Je n'aime pas ce style, et préfère utiliser un HOF. Cette tentative est trop détaillé pour être acceptable:
scala> listOfOptions.flatMap(opt => if (opt.isDefined) Some(opt.get) else None)
res1: List[java.lang.String] = List(hi)
Intuitivement je me serais attendu à la suite de travailler, mais il n'a pas d':
scala> List.flatten(listOfOptions)
<console>:6: error: type mismatch;
found : List[Option[java.lang.String]]
required: List[List[?]]
List.flatten(listOfOptions)
Même les éléments suivants qui semble comme il devrait fonctionner, mais n'a pas:
scala> listOfOptions.flatMap(_: Option[String])
<console>:6: error: type mismatch;
found : Option[String]
required: (Option[java.lang.String]) => Iterable[?]
listOfOptions.flatMap(_: Option[String])
^
Du mieux que je peux venir avec est:
scala> listOfOptions.flatMap(_.toList)
res2: List[java.lang.String] = List(hi)
... mais je préférerais ne pas avoir à convertir l'option d'une liste. Qui semble maladroit.
Des conseils?
Vous devez vous connecter pour publier un commentaire.
En Scala 2.8, aplatir fonctionne:
Cela ne fonctionne pas dans 2.7.7, cependant:
Les collections de la bibliothèque a été repensée, et s'est beaucoup amélioré dans la 2.8, donc peut-être que vous pourriez essayer d'utiliser la dernière Scala 2.8 RC et voir si cela rend plus facile à utiliser pour vous.
Si vraiment vous ne voulez pas utiliser le toList méthode, je suppose que vous pouvez aussi l'écrire comme ceci:
Pas non plus une chose de la beauté peut-être, mais au moins cela fonctionne dans 2.7.7.
Pour compléter Arjan réponse, en Scala 2.7.7 vous pouvez utiliser
List#flatten
, mais vous avez besoin pour aider le type inferencer: