【问题标题】:Extracting a value from an option inside an option in Scala从Scala中的选项内的选项中提取值
【发布时间】:2013-01-17 15:47:36
【问题描述】:

鉴于以下情况:

val x = Some(Some(1))

获得 1(如果不存在则为 -1)的最干净的方法是什么?

我正在从数据库查询返回的元组创建一个对象实例。元组中的一个值看起来像这样,所以我想要一个简短的“单线”来获取值或将参数设置为 -1。

【问题讨论】:

    标签: scala slick


    【解决方案1】:

    x.flatten 是您正在寻找的。在这里它会给你Some(1)。 如果您真的想在“那个不存在”的情况下获得-1,只需执行x.flatten.getOrElse(-1)

    scala> Some(Some(1)).flatten.getOrElse(-1)
    res1: Int = 1
    scala> Some(None).flatten.getOrElse(-1)
    res2: Int = -1
    scala> None.flatten.getOrElse(-1)
    res3: Int = -1
    

    【讨论】:

    • 展平!!!我读过它,我看过它,我用过它......现在只是为了记住它;-)
    【解决方案2】:

    为了理解通常是使用这些嵌套结构的一种非常易读的方式:

      val x = Some(Some(1))
      val result = for {
        firstLevel <- x
        secondLevel <- firstLevel
      } yield {
        // We've got an int, now transform it!
        (secondLevel * 100).toString
      }
    

    结果是一个 Option[String],只有当你有两个 Some(s) 时才会发生转换。

    你也可以使用模式匹配:

      val result2 = for {
        Some(v) <- x
      } yield {
        // We've got a int, now transform it!
        (v * 100).toString
      }
    

    【讨论】:

      【解决方案3】:

      虽然不是“单行”,但您可以创建一个函数来提取值。如果您将其设为通用并传入默认值,它可能会非常方便。

      scala> def fetchFromOptions[A](default: A)(x: Option[Option[A]]) = x match {
           | case Some(Some(a)) => a
           | case _ => default
           | }
      fetchFromOptions: [A](default: A)(x: Option[Option[A]])A
      
      scala> fetchFromOptions(-1)(Some(Some(1)))
      res0: Int = 1
      
      scala> fetchFromOptions(-1)(Some(None))
      res1: Int = -1
      

      【讨论】:

        【解决方案4】:

        这是我想出的:

        scala> val x = Some(Some(1))
        x: Some[Some[Int]] = Some(Some(1))
        
        scala> val y = x.map(_.getOrElse(-1)).get
        y: Int = 1
        
        scala> val x = Some(None)
        x: Some[None.type] = Some(None)
        
        scala> val y = x.map(_.getOrElse(-1)).get
        y: Int = -1
        

        这仅适用于您的第一级 Some 不是 None

        【讨论】:

        • +1 这正是我所走的道路之一 ;-) 那和“匹配”,但我知道有一种方法可以一劳永逸,但不记得如何。不过,Flatten 确实具有我一直在寻找的魔力。
        • 是的,其他解决方案显然更好。我也总是忘记扁平化。 ;-)
        【解决方案5】:

        如果你真的知道它的Some(Some(1)),那么你可以使用无可辩驳的模式匹配表示法:

        scala> val ssi1 = Some(Some(1))
        ssi1: Some[Some[Int]] = Some(Some(1))
        
        scala> val Some(Some(i1)) = ssi1
        i1: Int = 1
        

        如果组合中可能存在任何None,那么您必须使用其他人建议的更加谨慎和详细的形式。

        对于那些觉得这是一个奇怪的符号的人,可以把它想象成你在 case 中写的 match 构造或 PartialFunction 文字,以匹配 Some(Some(1)) 的审查员。

        【讨论】:

          猜你喜欢
          • 2020-07-01
          • 1970-01-01
          • 2018-05-04
          • 1970-01-01
          • 2020-06-03
          • 2022-07-16
          • 1970-01-01
          • 1970-01-01
          • 2014-03-16
          相关资源
          最近更新 更多