scala превращает итератор[Option[T]] в Итератор[T]
-
21-08-2019 - |
Вопрос
У меня есть Iterator[Option[T]]
и я хочу получить Iterator[T]
для тех, кто Option
s где T
isDefined
.Должен быть способ получше этого:
it filter { _ isDefined} map { _ get }
Я бы подумал, что это возможно в одной конструкции...У кого-нибудь есть идеи?
Решение
В том случае , когда 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
Другие советы
В более новых версиях это теперь возможно:
val it: Iterator[Option[T]] = ...
val flatIt = it.flatten
Это работает для меня (Scala 2.8):
it.collect {case Some(s) => s}
Для меня это классический вариант использования монадического пользовательского интерфейса.
for {
opt <- iterable
t <- opt
} yield t
Это просто сахар для flatMap
решение, описанное выше, и оно выдает идентичный байт-код.Однако синтаксис имеет значение, и я думаю, что сейчас один из лучших моментов для использования монадического интерфейса Scala for
синтаксис - это когда вы работаете с Option
, особенно в сочетании с коллекциями.
Я думаю, что эта формулировка значительно более удобочитаема, особенно для тех, кто не очень знаком с функциональным программированием.Я часто пробую как монадические, так и функциональные выражения цикла и вижу, какое из них кажется более простым.Я думаю, что Плоская карта это трудное название для большинства людей, чтобы грокнуть (и на самом деле, называя это >>=
для меня это имеет более интуитивный смысл).