取消选择选项

时间:2011-05-11 17:42:14

标签: scala join option monads flatten

说我有val s: Option[Option[String]]。因此它可以具有以下值:

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

我想减少它,以便第一个变为Some("foo"),而另外两个变为None。显然有很多方法可以实现这一目标,但我正在寻找一种简单的,可能内置的,不到一线的。

6 个答案:

答案 0 :(得分:35)

遗憾的是flatten不存在。它应该。

Flatten现在确实存在。

和以前一样,

s getOrElse None

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

答案 1 :(得分:16)

您可以使用scalaz join来执行此操作,因为这是 monadic 操作之一:

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的类型类实例的东西都可用。

答案 2 :(得分:13)

s.flatten

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

答案 3 :(得分:4)

我认为转换为Iterable很好。使用以下步骤从Option[Option[String]转到单个Option[String]

s.flatten.headOption 

(返回Option[String]

答案 4 :(得分: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]]展平为Option[Int]

答案 5 :(得分:-4)

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

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

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