将 List[Either[A, B]] 扁平化为 List[B] 就像 List[Option[B]] 到 List[B]
Flatten List[Either[A, B]] to List[B] like List[Option[B]] to List[B]
猫是否提供类似于
的扁平化
implicit class FlattenListOfEither[L, R](l: List[Either[L, R]]) {
def flattenM: List[R] = l collect { case Right(v) => v }
}
这样
val l1: List[Either[String, Int]] = List(Right(1), Right(2), Left("error"), Right(4))
l1.flattenM
产出
List(1, 2, 4)
类似于 vanilla Scala 扁平化选项列表的方式
val l2: List[Option[Int]] = List(Some(1), Some(2), None, Some(4))
l2.flatten
输出
List(1, 2, 4)
separate
给出以下语法
import cats.implicits._
val (_, rights) = l1.separate
rights
输出
List(1, 2, 4)
然而,是否存在开箱即用的 flatten
类扩展方法,returns 只是权限而不是元组?
Scala 2.13
中的partitionMap
呢? (请注意 shorter
是什么意思):
val l1: List[Either[String, Int]] = List(Right(1), Right(2), Left("error"), Right(4))
val (_, rights) = l1.partitionMap(identity)
println(rights)
// Displays
// List(1, 2, 4)
我认为最简单的方法是使用 FunctorFilter
类型类提供的 mapFilter
。
它看起来像这样:
def mapFilter[A, B](fa: F[A])(f: (A) ⇒ Option[B]): F[B]
其中 F[A]
可以是 List[A]
,或 Vector[A]
或任何其他允许过滤的类型。
如果我们将此函数应用于您的列表,我们只需要将 Either[A, B]
转换为 Option[B]
即可。这就像调用 toOption
一样简单。
完整的解决方案如下所示:
import cats.implicits._
val l1: List[Either[String, Int]] = List(Right(1), Right(2), Left("error"), Right(4))
l1.mapFilter(_.toOption)
// List(1, 2, 4)
我只想说
listOfEithers.flatMap(_.toOption)
使用普通的香草 Scala 收集方法似乎可以满足您的要求:
val x = List(Right(1), Right(2), Left("error"), Right(4))
x.flatMap(_.toOption) // res0: List[Int] = List(1, 2, 4)
猫是否提供类似于
的扁平化implicit class FlattenListOfEither[L, R](l: List[Either[L, R]]) {
def flattenM: List[R] = l collect { case Right(v) => v }
}
这样
val l1: List[Either[String, Int]] = List(Right(1), Right(2), Left("error"), Right(4))
l1.flattenM
产出
List(1, 2, 4)
类似于 vanilla Scala 扁平化选项列表的方式
val l2: List[Option[Int]] = List(Some(1), Some(2), None, Some(4))
l2.flatten
输出
List(1, 2, 4)
separate
给出以下语法
import cats.implicits._
val (_, rights) = l1.separate
rights
输出
List(1, 2, 4)
然而,是否存在开箱即用的 flatten
类扩展方法,returns 只是权限而不是元组?
Scala 2.13
中的partitionMap
呢? (请注意 shorter
是什么意思):
val l1: List[Either[String, Int]] = List(Right(1), Right(2), Left("error"), Right(4))
val (_, rights) = l1.partitionMap(identity)
println(rights)
// Displays
// List(1, 2, 4)
我认为最简单的方法是使用 FunctorFilter
类型类提供的 mapFilter
。
它看起来像这样:
def mapFilter[A, B](fa: F[A])(f: (A) ⇒ Option[B]): F[B]
其中 F[A]
可以是 List[A]
,或 Vector[A]
或任何其他允许过滤的类型。
如果我们将此函数应用于您的列表,我们只需要将 Either[A, B]
转换为 Option[B]
即可。这就像调用 toOption
一样简单。
完整的解决方案如下所示:
import cats.implicits._
val l1: List[Either[String, Int]] = List(Right(1), Right(2), Left("error"), Right(4))
l1.mapFilter(_.toOption)
// List(1, 2, 4)
我只想说
listOfEithers.flatMap(_.toOption)
使用普通的香草 Scala 收集方法似乎可以满足您的要求:
val x = List(Right(1), Right(2), Left("error"), Right(4))
x.flatMap(_.toOption) // res0: List[Int] = List(1, 2, 4)