我有一些代码,如下所示,我有一个Eithers列表,我想把它变成一个列表...特别是(在这种情况下),如果列表中有任何Lefts,那么我返回a列表的左侧,否则我返回权利列表的权利.
val maybe: List[Either[String, Int]] = getMaybe
val (strings, ints) = maybe.partition(_.isLeft)
strings.map(_.left.get) match {
case Nil => Right(ints.map(_.right.get))
case stringList => Left(stringList)
}
Run Code Online (Sandbox Code Playgroud)
打电话get总让我觉得我必须遗漏一些东西.
有没有比较惯用的方法呢?
Vik*_*ang 22
data.partition(_.isLeft) match {
case (Nil, ints) => Right(for(Right(i) <- ints) yield i)
case (strings, _) => Left(for(Left(s) <- strings) yield s)
}
Run Code Online (Sandbox Code Playgroud)
一次通过:
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)
}
Run Code Online (Sandbox Code Playgroud)
Scala中的函数式编程解决方案.
def sequence[E,A](es: List[Either[E,A]]): Either[E,List[A]] =
traverse(es)(x => x)
def traverse[E,A,B](es: List[A])(f: A => Either[E, B]): Either[E, List[B]] =
es match {
case Nil => Right(Nil)
case h::t => (f(h) map2 traverse(t)(f))(_ :: _)
}
def map2[EE >: E, B, C](a: Either[E, A], b: Either[EE, B])(f: (A, B) => C):
Either[EE, C] = for { a1 <- a; b1 <- b } yield f(a1,b1)
Run Code Online (Sandbox Code Playgroud)
val list = List(Left("x"),Right(2), Right(4))
val strings = for (Left(x) <- list) yield(x)
val result = if (strings.isEmpty) Right(for (Right(x) <- list) yield(x))
else Left(strings)
Run Code Online (Sandbox Code Playgroud)
首先Scala 2.13,现在为大多数集合提供了一种partitionMap方法,该方法根据返回Right或的函数对元素进行分区Left。
在我们的情况下,我们甚至不需要一个将输入转换为Right或Left定义分区的函数,因为我们已经有Rights和Lefts了。因此简单的使用identity!
然后,只需根据是否有剩余来匹配得到的左和右分区元组,这很简单:
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))
Run Code Online (Sandbox Code Playgroud)
为了理解partitionMap这里是中间步骤的结果:
List(Right(3), Left("error x"), Right(7)).partitionMap(identity)
// (List[String], List[Int]) = (List(error x), List(3, 7))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8718 次 |
| 最近记录: |