15

大多数 SQL 实现(这个问题与 SQL 无关,它只是一个例子)提供COALESCE(x1,x2,...,xn)返回x1if it is not的函数NULLx2否则只有 if x2is not notNULL两者等等。如果所有xi值都是,NULL则结果为NULL

我想COALESCE在 Scala 中获得类似 SQL 的东西,以便将OptionNULL替换为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 的一部分实现的东西。

4

4 回答 4

18

更短一点,您可以使用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
于 2015-03-24T13:57:04.760 回答
10

自动应答:

本机机制(不实现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
于 2015-03-24T17:41:11.017 回答
7

怎么样:

values.flatten.headOption

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

于 2015-03-24T13:58:30.963 回答
3

查找第一个定义的选项:

def coalesce[T](values: Option[T]*): Option[T] =
  values.find(_.isDefined).flatten
于 2015-03-24T13:42:26.257 回答