Un-optioning an optioned Option

后端 未结 6 1138
甜味超标
甜味超标 2021-02-02 07:05

Say I have a val s: Option[Option[String]]. It can thus have the following values:

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

相关标签:
6条回答
  • 2021-02-02 07:08

    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].

    0 讨论(0)
  • 2021-02-02 07:10

    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.

    0 讨论(0)
  • 2021-02-02 07:24

    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.

    0 讨论(0)
  • 2021-02-02 07:28

    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])

    0 讨论(0)
  • 2021-02-02 07:30
    s.flatten
    

    followed by a bunch of characters to get me up to the minimum that stackoverflow allows

    0 讨论(0)
  • 2021-02-02 07:32

    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
    
    0 讨论(0)
提交回复
热议问题