scala transformando um Repetidor [Opção [T]] em um Repetidor [T]
-
21-08-2019 - |
Pergunta
Eu tenho um Iterator[Option[T]]
e eu quero ter uma Iterator[T]
para aqueles Option
s onde T
isDefined
. Deve haver uma maneira melhor do que este:
it filter { _ isDefined} map { _ get }
Eu teria pensado que era possível em uma construção ... Alguém alguma idéia?
Solução
No caso em que it
é um Iterable
val it:Iterable[Option[T]] = ...
it.flatMap( x => x ) //returns an Iterable[T]
No caso em que it
é um Iterator
val it:Iterator[Option[T]] = ...
it.flatMap( x => x elements ) //returns an Iterator[T]
it.flatMap( _ elements) //equivalent
Outras dicas
Em versões mais recentes isso agora é possível:
val it: Iterator[Option[T]] = ...
val flatIt = it.flatten
Isso funciona para mim (Scala 2.8):
it.collect {case Some(s) => s}
Para mim, este é um caso de uso clássico para a interface do usuário monádico.
for {
opt <- iterable
t <- opt
} yield t
É apenas açúcar para a solução flatMap
descrito acima, e que produz bytecode idênticos. Contudo, as questões de sintaxe, e eu acho que um dos melhores momentos para usar sintaxe for
monádico do Scala é quando você está trabalhando com Option
, especialmente em conjunto com coleções.
Eu acho que esta formulação é consideravelmente mais legível, especialmente para aqueles não muito familiarizados com programação funcional. Muitas vezes eu tento tanto as expressões monádicas e funcionais de um loop e ver o que parece mais simples. Acho flatMap é o nome difícil para a maioria das pessoas Grokar (e, na verdade, chamando->>=
faz sentido mais intuitivo para mim).