大多数SQL实现(这个问题与SQL无关,只是一个例子)提供函数COALESCE(x1,x2,...,xn)
,如果它不是x1
,则返回NULL
,{{1 }}仅当x2
不是x2
时才这样,等等。如果所有NULL
值均为xi
,则结果为NULL
。
我想在Scala中获得类似SQL NULL
的内容,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的一部分实现此功能。
答案 0 :(得分:12)
还可以使用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
答案 1 :(得分:7)
怎么样:
values.flatten.headOption
这可行,因为Option
可隐式转换为Iterable
,因此flatten
与列表列表的工作方式相同。
答案 2 :(得分:6)
自动回答:
本机机制(没有实现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 :(得分:3)
找到第一个定义的选项:
def coalesce[T](values: Option[T]*): Option[T] =
values.find(_.isDefined).flatten