假设我有一个val s: Option[Option[String]]
。它可能会有以下几种值:
Some(Some("foo"))
Some(None)
None
我想将其简化,使第一个变为Some("foo")
,而其他两个变为None
。显然,有很多方法可以实现这一点,但我正在寻找一个简单的、内置的、不到一行代码的方法。
假设我有一个val s: Option[Option[String]]
。它可能会有以下几种值:
Some(Some("foo"))
Some(None)
None
我想将其简化,使第一个变为Some("foo")
,而其他两个变为None
。显然,有很多方法可以实现这一点,但我正在寻找一个简单的、内置的、不到一行代码的方法。
很遗憾flatten
不存在。它应该存在。
现在flatten
已经存在了。
与以前一样,
s getOrElse None
< p >(除了其他答案之外)也会做同样的事情。你可以使用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类型类实例的对象都可以使用它。
val map = Map("a"->Some(Some(1)), "b"->2)
的映射,当我调用map.get("a").join
时,我看到了could not find implicit value for parameter ev: scalaz.Liskov.<~<[Any,Option[B]]
的错误提示。 - bachrs.flatten
紧随其后的一堆字符,以使我达到stackoverflow允许的最低要求
s.flatmap(x=>x)
代替。 - Dave Griffiths flatMap identity
来表示。 - Frank S. ThomasList(Some(Some("foo")), Some(None), None) map { _ flatMap identity }
产生 List[Option[java.lang.String]] = List(Some(foo), None, None)
,这就是我认为 Knut(楼主和我听说过的第一个非北极熊崽子名叫“Knut”)想要的。 - Michael Lorton我认为将其转换为可迭代对象是可行的。按照以下步骤,从Option[Option[String]
转换为单个Option[String]
:
s.flatten.headOption
Option[String]
的值)val options = List(Some(Some(1)), Some(None), None)
options map (_ flatMap (a => a))
这将把 List [Option [Option [Int]]]
映射到 List [Option [Int]]
。
如果你只有一个 Option,你可以按照以下方式使用它:
val option = Some(Some(2))
val unzippedOption = option flatMap (b => b)
Option[Option[Int]]
扁平化为 Option[Int]
。嗯,我其实不明白为什么它可能只是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
None
,因为它是一个Option
! - oxbow_lakesSome(Some(X))
是一个计算出的值,Some(None)
表示未来已经完成但没有任何值,None
表示未来尚未返回。 - oxbow_lakes
Some(Some(Some(1)))
这样的对象调用flatten
时,我会得到Cannot prove that Any <:< Option[B]
的错误提示。 - bachr