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 - это трудное имя для большинства людей, которым грозит (и на самом деле его вызов >>= делает для меня более интуитивно понятным).