【问题标题】:Coalescing options in ScalaScala 中的合并选项
【发布时间】:2015-03-24 13:34:20
【问题描述】:

大多数SQL实现(这个问题与SQL无关,只是一个例子)提供函数COALESCE(x1,x2,...,xn),如果它不是x1,则返回NULLx2否则仅当x2不是NULL 也不是等等。如果所有xi 的值都是NULL,那么结果就是NULL

我想在 Scala 中获得类似于 SQL 的 COALESCE 的东西,因为 Option 的值被 NULL 替换为 None。我给你举几个例子:

> coalesce(None,Some(3),Some(4))
res0: Some(3)

> coalesce(Some(1),None,Some(3),Some(4))
res1: Some(1)

> coalesce(None,None)
res2: None

所以我将它实现为:

def coalesce[T](values: Option[T]*): Option[T] = 
    (List[T]() /: values)((prev: List[T], cur: Option[T]) =>
                          prev:::cur.toList).headOption

它工作正常,但我想知道是否已经存在类似这个函数作为 Scala 的一部分实现的东西。

【问题讨论】:

标签: scala scala-option


【解决方案1】:

更短一点,您可以使用collectFirst。这将一步完成,最多遍历一次集合。

def coalesce[A](values: Option[A]*): Option[A] =
    values collectFirst { case Some(a) => a }


scala> coalesce(Some(1),None,Some(3),Some(4))
res15: Option[Int] = Some(1)

scala> coalesce(None,None)
res16: Option[Nothing] = None

【讨论】:

    【解决方案2】:

    自动回答:

    本机机制(未实现coalesce 函数)是对orElse 方法的调用链:

    > None.orElse(Some(3)).orElse(Some(4))
    res0: Option[Int] = Some(3)
    
    > Some(1).orElse(None).orElse(Some(3)).orElse(Some(4))
    res1: Option[Int] = Some(1)
    
    > None.orElse(None)
    res2: Option[Nothing] = None
    

    【讨论】:

      【解决方案3】:

      怎么样:

      values.flatten.headOption
      

      这是因为Option 可以隐式转换为Iterable,所以flatten 的工作方式与列表列表的工作方式非常相似。

      【讨论】:

        【解决方案4】:

        找到第一个定义的选项:

        def coalesce[T](values: Option[T]*): Option[T] =
          values.find(_.isDefined).flatten
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-08
          • 2021-02-21
          相关资源
          最近更新 更多