Scala 中的合并选项

Coalescing options in Scala

大多数 SQL 实现(这个问题与 SQL 无关,它只是一个例子)提供函数 COALESCE(x1,x2,...,xn) 其中 returns x1 如果它不是 NULL,则 x2 否则仅当 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 的一部分实现的类似此功能的东西。

找到第一个定义的选项:

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

更短的,您可以使用 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

怎么样:

values.flatten.headOption

这是有效的,因为 Option 可以隐式转换为 Iterable,因此 flatten 的工作方式与列表的列表相同。

自动回答:

本机机制(未实现 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