scala tournant un itérateur [Option [T]] dans un itérateur [T]
-
21-08-2019 - |
Question
J'ai une et je veux Iterator[Option[T]]
obtenir un pour les Iterator[T]
s où Option
T
isDefined
. Il doit y avoir une meilleure façon que cela:
it filter { _ isDefined} map { _ get }
J'aurais pensé qu'il était possible dans une construction ... Quelqu'un des idées?
La solution
Dans le cas où est un it
Iterable
val it:Iterable[Option[T]] = ...
it.flatMap( x => x ) //returns an Iterable[T]
Dans le cas où est un Iterator
<=>
val it:Iterator[Option[T]] = ...
it.flatMap( x => x elements ) //returns an Iterator[T]
it.flatMap( _ elements) //equivalent
Autres conseils
Dans les nouvelles versions cela est désormais possible:
val it: Iterator[Option[T]] = ...
val flatIt = it.flatten
Cela fonctionne pour moi (Scala 2.8):
it.collect {case Some(s) => s}
Pour moi, cela est un cas d'utilisation classique pour l'interface utilisateur monadique.
for {
opt <- iterable
t <- opt
} yield t
Il est juste de sucre pour la solution décrite ci-dessus flatMap
, et produit bytecode identiques. Toutefois, les questions de syntaxe, et je pense que l'un des meilleurs moments pour utiliser la syntaxe monadique Scala est for
lorsque vous travaillez avec Option
, en particulier en conjonction avec des collections.
Je pense que cette formulation est beaucoup plus facile à lire, en particulier pour ceux qui ne connaissent pas bien la programmation fonctionnelle. J'essaie souvent à la fois les expressions monades et fonctionnelles d'une boucle et voir ce qui semble plus simple. Je pense que flatMap est le nom difficile pour la plupart des gens à digèrent (et en fait, l'appelant me fait >>=
sens plus intuitive).