Scala convierte un Iterador [Opción [T]] en un Iterador [T]
-
21-08-2019 - |
Pregunta
Yo tengo un Iterator[Option[T]]
y quiero conseguir un Iterator[T]
para esos Option
es donde T
isDefined
.Debe haber una manera mejor que esta:
it filter { _ isDefined} map { _ get }
Pensé que era posible en una sola construcción...¿Alguien tiene alguna idea?
Solución
En el caso en it
es un Iterable
val it:Iterable[Option[T]] = ...
it.flatMap( x => x ) //returns an Iterable[T]
En el caso en Iterator
es un <=>
val it:Iterator[Option[T]] = ...
it.flatMap( x => x elements ) //returns an Iterator[T]
it.flatMap( _ elements) //equivalent
Otros consejos
En las nuevas versiones esto es ahora posible:
val it: Iterator[Option[T]] = ...
val flatIt = it.flatten
Esto funciona para mí (Scala 2.8):
it.collect {case Some(s) => s}
Para mí, este es un caso de uso clásico para la interfaz de usuario monádico.
for {
opt <- iterable
t <- opt
} yield t
Es sólo azúcar para la solución flatMap
descrito anteriormente, y produce código de bytes idénticos. Sin embargo, las cuestiones de sintaxis, y creo que uno de los mejores momentos de usar la sintaxis de monádico Scala for
es cuando se trabaja con Option
, especialmente en conjunción con colecciones.
Creo que esta formulación es considerablemente más fácil de leer, especialmente para aquellos que no están muy familiarizados con la programación funcional. A menudo trato tanto las expresiones monádicos y funcionales de un bucle y veo que parece más sencillo. Creo que flatMap es el nombre difícil para la mayoría de la gente asimilar (y, de hecho, llamándolo >>=
tiene sentido más intuitivo para mí).