Combining two [List [String]] options in Scala

I have two options

val opt1 = Some(List("Sal", "Salil")) val opt2 = Some(List("Sal2", "Salil2")) 

Either opt1 or opt2 can be None. If one of them is “No,” then I need an option with a list, which is contained in another. If both parameters are None, then None must be returned.

If both are Some, then a Some with a list containing items from both lists, as shown below:

 Some(List(Sal, Salil, Sal2, Salil2)) 

I know I can do it manually, but is there an elegant way to do this? For-understanding does not work if one of the parameters is None.

+5
source share
3 answers
 Option((opt1 ++ opt2).flatten.toList).filter(_.nonEmpty) 
+6
source

You can do it beautifully using a semigroup adding with a fairy tale or cats:

 import scalaz._, Scalaz._ // for cats use `import cats._, implicits._` val opt1 = Option(List("Sal", "Salil")) val opt2 = Option(List("Sal2", "Salil2")) scala> opt1 |+| opt2 res0: Option[List[String]] = Some(List(Sal, Salil, Sal2, Salil2)) scala> opt1 |+| None res1: Option[List[String]] = Some(List(Sal, Salil)) scala> Option.empty[List[String]] |+| None res2: Option[List[String]] = None 

Otherwise, with the standard library, you may need to process it in each case:

 (opt1, opt2) match { case (Some(a), Some(b)) => Option(a ++ b) case (Some(a), None) => Option(a) case (None, Some(b)) => Option(b) case _ => None } 

Or use collection methods to smooth them:

 scala> List(opt1, opt2).flatten.flatten res5: List[String] = List(Sal, Salil, Sal2, Salil2) scala> List(opt1, None).flatten.flatten res6: List[String] = List(Sal, Salil) 
+5
source

I do not think that there is only one, correct, elegant way to achieve this. There is my suggestion:

 val opt1 = Some(List("Sal", "Salil")) val opt2 = Some(List("Sal2", "Salil2")) def merge(xs: Option[Iterable[_]]*) = xs.flatten.reduceLeftOption(_ ++ _) 

With the results:

 merge (opt1, opt2) res1: Option[Iterable[_]] = Some(List(Sal, Salil, Sal2, Salil2)) merge (None, opt2) res2: Option[Iterable[_]] = Some(List(Sal2, Salil2)) merge (opt1, None) res5: Option[Iterable[_]] = Some(List(Sal, Salil)) merge (None, None) res6: Option[Iterable[_]] = None 
+3
source

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


All Articles