27

List[Either[A, B]]aを 2 つのリストに分割したい。

より良い方法はありますか?

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}
4

8 に答える 8

26

これが本当にきれいかどうかはわかりませんが、次のとおりです。

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")
于 2014-10-26T19:01:47.987 に答える
9

あなたはそれを行うことができます:

val (lefts, rights) = eithers.foldRight((List[Int](), List[String]()))((e, p) => e.fold(l => (l :: p._1, p._2), r => (p._1, r :: p._2)))
于 2014-10-26T23:16:42.610 に答える
1

まあ、それがワンライナーである必要がない場合は...それなら簡単にできます。

def split[A,B](eithers : List[Either[A, B]]):(List[A],List[B]) = {
  val lefts = scala.collection.mutable.ListBuffer[A]()
  val rights = scala.collection.mutable.ListBuffer[B]()
  eithers.map {
    case Left(l) => lefts += l
    case Right(r) => rights += r
  }
  (lefts.toList, rights.toList)
}

しかし、正直に言うと、私はマルスの答えを好むでしょう:)

于 2014-10-27T13:11:57.533 に答える