41

说我有一个val s: Option[Option[String]]. 因此,它可以具有以下值:

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

我想减少它,以便第一个成为Some("foo")而其他两个成为None。显然有很多方法可以做到这一点,但我正在寻找一种简单的,也许是内置的,少于一个班轮的。

4

6 回答 6

37

这是一种flatten不存在的耻辱。它应该。

Flatten 现在确实存在。

像之前一样,

s getOrElse None

(除了其他答案)也会做同样的事情。

于 2011-05-11T20:43:17.103 回答
16

您可以使用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

它适用于任何具有 Monad 的类型类实例的东西。

于 2011-05-11T18:03:43.890 回答
14
s.flatten

后面跟着一堆字符让我达到stackoverflow允许的最小值

于 2011-05-11T17:50:36.690 回答
4

我认为转换到 Iterable 就好了。使用这些步骤从Option[Option[String]单个Option[String]

s.flatten.headOption 

(返回Option[String]

于 2011-11-02T18:46:52.813 回答
1

您可以像下面这样使用 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]]to变平Option[Int]

于 2012-05-07T12:06:09.807 回答
-4

好吧,我实际上不明白为什么它可能只是 None (第三种情况)。如果它真的也可以只是 None,那么我会投票支持 Rex Kerr 的答案,否则只需 .get 就足够了:

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

scala> Some(None).get
res1: None.type = None
于 2011-05-11T21:44:45.600 回答