Say I have a val s: Option[Option[String]]
. It can thus have the following values:
Some(Some("foo"))
Some(None)
None
I want to reduce it so that the first becomes Some("foo")
while the two others become None
. Obviously there are many ways to accomplish this, but I'm looking for a simple, perhaps built-in, less-than-one-liner.
It's a shame that flatten
doesn't exist. It should.
Flatten does exist now.
As before,
s getOrElse None
(in addition to the other answers) will also do the same thing.
You could use scalaz join
to do this, as this is one of the monadic operations:
doubleOpt.join
Here it is in the 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
It's available to anything with a typeclass instance for a Monad.
s.flatten
followed by a bunch of characters to get me up to the minimum that stackoverflow allows
I think the conversion to the Iterable is just fine. Use these steps to go from Option[Option[String]
to a single Option[String]
s.flatten.headOption
(which returns Option[String]
)
You might use flatMap like the following:
val options = List(Some(Some(1)), Some(None), None)
options map (_ flatMap (a => a))
This will map the List[Option[Option[Int]]]
to a List[Option[Int]]
.
If you just have an Option you can use it as following:
val option = Some(Some(2))
val unzippedOption = option flatMap (b => b)
This will flatten your Option[Option[Int]]
to Option[Int]
.
Well, I actually don't understand how come it could be just None (the third case). If it can really be also just None, then I would vote for Rex Kerr's answer, otherwise just .get would be enough:
scala> Some(Some("foo")).get
res0: Some[java.lang.String] = Some(foo)
scala> Some(None).get
res1: None.type = None