Scala превращает Iterator [Option [T]] в Iterator [T] - PullRequest
10 голосов
/ 20 марта 2009

У меня есть Iterator[Option[T]], и я хочу получить Iterator[T] для тех Option s, где T isDefined. Должен быть лучший способ, чем этот:

it filter { _ isDefined} map { _ get }

Я бы подумал, что это возможно в одной конструкции ... У кого-нибудь есть идеи?

Ответы [ 4 ]

14 голосов
/ 21 марта 2009

В случае, когда 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
11 голосов
/ 21 февраля 2011

В новых версиях это теперь возможно:

val it: Iterator[Option[T]] = ...
val flatIt = it.flatten
5 голосов
/ 24 февраля 2011

Это работает для меня (Scala 2.8):

it.collect {case Some(s) => s}
3 голосов
/ 25 апреля 2011

Для меня это классический вариант использования монадического интерфейса.

for {
  opt <- iterable
  t   <- opt
} yield t

Это просто сахар для решения flatMap, описанного выше, и он выдает идентичный байт-код. Однако синтаксис имеет значение, и я думаю, что один из лучших вариантов использования монадического синтаксиса Scala for - это когда вы работаете с Option, особенно в сочетании с коллекциями.

Я думаю, что эта формулировка значительно более читабельна, особенно для тех, кто не очень знаком с функциональным программированием. Я часто пробую как монадические, так и функциональные выражения цикла и вижу, что кажется более простым. Я думаю, что flatMap - это жесткое имя для большинства людей, которое нужно выкрикивать (и на самом деле, называя его >>=, для меня это более интуитивно понятно).

...