Best way to turn a Lists of Eithers into an Either of Lists?

前端 未结 9 1857
轮回少年
轮回少年 2020-12-13 13:14

I have some code like the below, where I have a list of Eithers, and I want to turn it into an Either of Lists ... in particular (in this case), if there are any Lefts in th

相关标签:
9条回答
  • 2020-12-13 13:49

    Starting in Scala 2.13, most collections are now provided with a partitionMap method which partitions elements based on a function returning 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 since we already have Rights and Lefts. Thus a simple use of identity!

    Then it's just a matter of matching the resulting partitioned tuple of lefts and rights based on whether or not there are any lefts:

    eithers.partitionMap(identity) match {
      case (Nil, rights) => Right(rights)
      case (lefts, _)    => Left(lefts)
    }
    // * List[Either[String, Int]] = List(Right(3), Left("error x"), Right(7))
    //         => Either[List[String],List[Int]] = Left(List(error x))
    // * List[Either[String, Int]] = List(Right(3), Right(7))
    //         => Either[List[String],List[Int]] = Right(List(3, 7))
    

    For the understanding of partitionMap here is the result of the intermediate step:

    List(Right(3), Left("error x"), Right(7)).partitionMap(identity)
    // (List[String], List[Int]) = (List(error x), List(3, 7))
    
    0 讨论(0)
  • 2020-12-13 13:51
    data.partition(_.isLeft) match {                            
      case (Nil,  ints) => Right(for(Right(i) <- ints) yield i)        
      case (strings, _) => Left(for(Left(s) <- strings) yield s)
    }
    

    For one pass:

    data.partition(_.isLeft) match {                            
      case (Nil,  ints) => Right(for(Right(i) <- ints.view) yield i)        
      case (strings, _) => Left(for(Left(s) <- strings.view) yield s)
    }
    
    0 讨论(0)
  • 2020-12-13 13:55

    If you want to have something more general and also functional then Validated from cats library is the type you might want. It is something like Either that can aggregate Errors. And in combination with NonEmptyList it can be really powerful.

    http://typelevel.org/cats/datatypes/validated.html

    0 讨论(0)
提交回复
热议问题