Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Coalescing options in Scala

Most SQL implementations (this question has nothing to do with SQL, it is just an example) offer the function COALESCE(x1,x2,...,xn) which returns x1 if it is not NULL, x2 otherwise only if x2 is not NULL neither and so on. If all xi values are NULL then the result is NULL.

I wanted to get something like SQL's COALESCE in Scala for Option values being NULL replaced by None. I'll give you some examples:

> 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

So I implemented it as:

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

It works fine but I wonder if already exists something like this function implemented as part of Scala.

like image 228
Pablo Francisco Pérez Hidalgo Avatar asked Mar 24 '15 13:03

Pablo Francisco Pérez Hidalgo


Video Answer


2 Answers

Shorter still, you could use collectFirst. This will do it in one step, with at most one traversal of the collection.

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
like image 177
Michael Zajac Avatar answered Sep 22 '22 06:09

Michael Zajac


Auto answer:

The native mechanism (without implementing a coalesce function) is the chaining of calls to orElse method:

> 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
like image 32
Pablo Francisco Pérez Hidalgo Avatar answered Sep 23 '22 06:09

Pablo Francisco Pérez Hidalgo