Отключение опции Option - PullRequest
38 голосов
/ 11 мая 2011

Скажите, у меня есть val s: Option[Option[String]].Таким образом, он может иметь следующие значения:

Some(Some("foo")) Some(None) None

Я хочу уменьшить его так, чтобы первое стало Some("foo"), а два других - None,Очевидно, что есть много способов сделать это, но я ищу простой, возможно, встроенный, меньше чем один вкладыш.

Ответы [ 6 ]

35 голосов
/ 12 мая 2011

Жаль, что flatten не существует. Стоит.

Flatten теперь существует.

Как и раньше,

s getOrElse None

(в дополнение к другим ответам) тоже сделает то же самое.

16 голосов
/ 11 мая 2011

Вы можете использовать scalaz join, чтобы сделать это, поскольку это одна из монадических операций:

doubleOpt.join

Вот оно в REPL:

scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._

scala> some(some("X")).join
res0: Option[java.lang.String] = Some(X)

scala> some(none[String]).join
res1: Option[String] = None

scala> none[Option[String]].join
res3: Option[String] = None

Он доступен для любого с экземпляром класса типов для Монады.

13 голосов
/ 11 мая 2011
s.flatten

, сопровождаемый кучей символов, чтобы получить до минимума, который позволяет stackoverflow

4 голосов
/ 02 ноября 2011

Я думаю, что преобразование в Iterable просто отлично. Используйте эти шаги для перехода от Option[Option[String] к одному Option[String]

s.flatten.headOption 

(который возвращает Option[String])

1 голос
/ 07 мая 2012

Вы можете использовать flatMap следующим образом:

val options = List(Some(Some(1)), Some(None), None)
options map (_ flatMap (a => a))

Это сопоставит List[Option[Option[Int]]] с List[Option[Int]].
Если у вас есть опция, вы можете использовать ее следующим образом:

val option = Some(Some(2))
val unzippedOption = option flatMap (b => b)

Это сгладит ваш Option[Option[Int]] до Option[Int].

0 голосов
/ 12 мая 2011

Ну, на самом деле я не понимаю, почему это может быть просто Нет (третий случай). Если это действительно может быть просто None, то я бы проголосовал за ответ Rex Kerr, иначе просто .get было бы достаточно:

scala> Some(Some("foo")).get
res0: Some[java.lang.String] = Some(foo)

scala> Some(None).get
res1: None.type = None
...