Scala 只映射右边的值和左边的显示错误

Scala map only right value and display error for left

我有一系列左右值,例如:

val l: Seq[Either[Error, Data]] = Seq(Left(Error), Right(Data), ...)

我想映射所有 Right 值并显示 Left 的错误。 我试过:

val data: Seq[Data] = l.flatMap {
  case Right(data) => data
  case Left(err)   => println(err) // doesn't work because println is Unit
}

有什么办法吗?

像这样混合副作用和纯代码通常不是一个很好的做法,但像这样(假设严格 Seq):

def rightsAfterEffectingLefts[A, B](eithers: Seq[Either[A, B]])(effect: A => Unit): Seq[B] = {
  eithers.foreach(_.left.foreach(effect))
  eithers.flatMap(_.toOption)
}

val data = rightsAfterEffectingLefts(l)(println _)

虽然您可能希望以不同的方式处理不同的 Seq 实现,但可以进行优化以避免双重迭代。

编辑:根据 Luis 的建议

def rightsAfterEffectingLefts[A, B](eithers: Seq[Either[A, B]])(effect: A => Unit): Seq[B] = {
  val (lefts, rights) = eithers.partition(_.isLeft)
  lefts.foreach(_.left.foreach(effect))
  rights.flatMap(_.toOption)
}

是另一种定义。它仍然会进行两次迭代,并且可能会更慢。

你的方向是正确的,只需要让 flatMap() 删除打印后的 Error

val data: Seq[Data] = l.flatMap {
  case Right(data) => Some(data)
  case Left(err)   => println(err); None
}

一次遍历即可。