【问题标题】:Scala map only right value and display error for leftScala仅映射右侧值并显示左侧错误
【发布时间】:2021-12-18 19:20:01
【问题描述】:

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

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
}

有什么办法吗?

【问题讨论】:

  • 不要试图同时做两件事,使用partitionMap将列表分成两部分,然后使用带有错误列表的foreach打印它们。

标签: scala either


【解决方案1】:

像这样混合副作用和纯代码通常不是一个好习惯,但类似(假设严格的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)
}

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

【讨论】:

  • 最好使用eithers.partitionMap(identity) :)
  • 是的,因为我打开的 scaladoc 窗口是 2.12,所以我的心态是 2.12 :)
【解决方案2】:

你在正确的轨道上,只需要让flatMap()在打印后删除Error

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

只需要一次遍历。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-31
    • 2015-04-05
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    • 2018-07-31
    相关资源
    最近更新 更多