scala Drehen eines Iterator [Option [T]] in einen Iterator [T]
-
21-08-2019 - |
Frage
Ich habe eine Iterator[Option[T]]
und ich möchte ein Iterator[T]
für jene Option
s wo T
isDefined
bekommen. Es muss ein besserer Weg, als dies:
it filter { _ isDefined} map { _ get }
Ich hätte gedacht, dass es möglich war, in einem Konstrukt ... jemand irgendwelche Ideen?
Lösung
In dem Fall, wo it
ein Iterable
ist
val it:Iterable[Option[T]] = ...
it.flatMap( x => x ) //returns an Iterable[T]
In dem Fall, wo it
ein Iterator
ist
val it:Iterator[Option[T]] = ...
it.flatMap( x => x elements ) //returns an Iterator[T]
it.flatMap( _ elements) //equivalent
Andere Tipps
In neueren Versionen ist dies nun möglich:
val it: Iterator[Option[T]] = ...
val flatIt = it.flatten
Dies funktioniert für mich (Scala 2.8):
it.collect {case Some(s) => s}
Für mich ist dies ein klassischer Anwendungsfall für die monadische UI.
for {
opt <- iterable
t <- opt
} yield t
Es ist nur Zucker für die flatMap
oben beschriebene Lösung, und es produziert identisch Bytecode. Allerdings Syntax Angelegenheiten, und ich denke, eine der besten Zeiten Scala monadischen for
Syntax zu verwenden ist, wenn Sie mit Option
arbeiten, vor allem in Verbindung mit Sammlungen.
Ich denke, diese Formulierung deutlich besser lesbar ist, vor allem für diejenigen, die nicht sehr vertraut mit dem funktionalen Programmierung. Ich versuche oft sowohl die monadische und Funktionsausdrücke einer Schleife und sehen, welche einfacher zu sein scheint. Ich denke, flatMap ist schwer Name für die meisten Menschen grok (und tatsächlich, nennt es >>=
macht intuitiven Sinn für mich).