Scala превращение итератора [Option [T]] в Iterator [T]
У меня есть Iterator[Option[T]]
, и я хочу получить Iterator[T]
для тех Option
, где T
isDefined
. Там должен быть лучший способ:
it filter { _ isDefined} map { _ get }
Я бы подумал, что это возможно в одной конструкции... У кого-нибудь есть идеи?
Ответы
Ответ 1
В случае, когда it
является Iterable
val it:Iterable[Option[T]] = ...
it.flatMap( x => x ) //returns an Iterable[T]
В случае, когда it
является Iterator
val it:Iterator[Option[T]] = ...
it.flatMap( x => x elements ) //returns an Iterator[T]
it.flatMap( _ elements) //equivalent
Ответ 2
В новых версиях это теперь возможно:
val it: Iterator[Option[T]] = ...
val flatIt = it.flatten
Ответ 3
Это работает для меня (Scala 2.8):
it.collect {case Some(s) => s}
Ответ 4
Для меня это классический вариант использования для монадического интерфейса.
for {
opt <- iterable
t <- opt
} yield t
Он просто сахара для решения flatMap
, описанного выше, и он производит одинаковый байт-код. Однако синтаксис имеет значение, и я думаю, что одним из лучших моментов использования синтаксиса Scala monadic for
является то, что вы работаете с Option
, особенно в сочетании с коллекциями.
Я думаю, что эта формулировка значительно читаема, особенно для тех, кто не очень хорошо разбирается в функциональном программировании. Я часто стараюсь как монадические, так и функциональные выражения цикла и вижу, что кажется более простым. Я думаю, что flatMap - это трудное имя для большинства людей, которым грозит (и на самом деле его вызов >>=
делает для меня более интуитивно понятным).