Scala Coalescence Options

Most SQL implementations (this question has nothing to do with SQL, this is just an example) offers a function COALESCE(x1,x2,...,xn) that returns x1 if it is not NULL , x2 otherwise, only if x2 not NULL and etc. If all xi are NULL , then the result is NULL .

I wanted to get something like SQL COALESCE in Scala for Option NULL values ​​instead of None . I will give 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 great, but it seems to me that there is already something like this function implemented as part of Scala.

+5
source share
4 answers

Even shorter, you can use collectFirst . This will do it in one step, with no more than one round 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 
+10
source

What about:

 values.flatten.headOption 

This works because Option implicitly converted to Iterable , so flatten works just like a list of lists.

+5
source

Find the first specific option:

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

Auto Answer:

The native mechanism (without implementing the coalesce function) is a chain of calls to the 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 
+3
source

Source: https://habr.com/ru/post/1216001/


All Articles