Scala trasformando un Iterator [Opzione [T]] in un Iterator [T]
-
21-08-2019 - |
Domanda
Ho un Iterator[Option[T]]
e voglio ottenere un Iterator[T]
per quei Option
s dove T
isDefined
. Ci deve essere un modo migliore di questo:
it filter { _ isDefined} map { _ get }
avrei pensato che fosse possibile in un costrutto ... Qualcuno tutte le idee?
Soluzione
Nel caso in cui it
è un Iterable
val it:Iterable[Option[T]] = ...
it.flatMap( x => x ) //returns an Iterable[T]
Nel caso in cui Iterator
è un <=>
val it:Iterator[Option[T]] = ...
it.flatMap( x => x elements ) //returns an Iterator[T]
it.flatMap( _ elements) //equivalent
Altri suggerimenti
Nelle versioni più recenti questo è ora possibile:
val it: Iterator[Option[T]] = ...
val flatIt = it.flatten
Questo funziona per me (Scala 2.8):
it.collect {case Some(s) => s}
Per me, questo è un caso d'uso classico per la monade UI.
for {
opt <- iterable
t <- opt
} yield t
E 'solo zucchero per la soluzione flatMap
sopra descritta, e produce bytecode identici. Tuttavia, le questioni di sintassi, e penso che uno dei periodi migliori per utilizzare la sintassi di Scala monadica for
è quando si lavora con Option
, soprattutto in combinazione con le collezioni.
Credo che questa formulazione è molto più leggibile, soprattutto per chi non è molto familiare con la programmazione funzionale. Mi capita spesso di provare sia le espressioni monadici e funzionali di un ciclo e vedo che sembra più semplice. Penso che flatMap è il nome difficile per la maggior parte delle persone di Grok (e in realtà, definendolo >>=
senso più intuitivo per me).