Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split a List[Either[A, B]]

Tags:

scala

either

I want to split a List[Either[A, B]] in two lists.

Is there a better way ?

def lefts[A, B](eithers : List[Either[A, B]]) : List[A] = eithers.collect { case Left(l) => l} def rights[A, B](eithers : List[Either[A, B]]) : List[B] = eithers.collect { case Right(r) => r} 
like image 780
Yann Moisan Avatar asked Oct 26 '14 18:10

Yann Moisan


2 Answers

Starting Scala 2.13, most collections are now provided with a partitionMap method which partitions elements based on a function which returns either Right or Left.

In our case, we don't even need a function that transforms our input into Right or Left to define the partitioning as we already have Rights and Lefts. Thus a simple use of identity:

val (lefts, rights) = List(Right(2), Left("a"), Left("b")).partitionMap(identity) // lefts: List[String] = List(a, b) // rights: List[Int] = List(2) 
like image 164
Xavier Guihot Avatar answered Sep 21 '22 19:09

Xavier Guihot


Not sure this is really much neater, but :

scala> def splitEitherList[A,B](el: List[Either[A,B]]) = {          val (lefts, rights) = el.partition(_.isLeft)          (lefts.map(_.left.get), rights.map(_.right.get))        } splitEitherList: [A, B](el: List[Either[A,B]])(List[A], List[B])  scala> val el : List[Either[Int, String]] = List(Left(1), Right("Success"), Left(42)) el: List[Either[Int,String]] = List(Left(1), Right(Success), Left(42))  scala> val (leftValues, rightValues) = splitEitherList(el) leftValues: List[Int] = List(1, 42) rightValues: List[String] = List("Success") 
like image 44
Marth Avatar answered Sep 20 '22 19:09

Marth