The*_*ude 4 functional-programming scala either
给定 a Set[Either[BadObject, GoodObject]],我想将其转换为 a Set[GoodObject],同时记录所有BadObjects.
我遇到的问题是,当我尝试在collect呼叫中添加日志记录时,例如:
someMethodThatReurnsTheSet.collect {
case Right(value) => value
case Left(res) => logger.warn(s"Bad object : $res")
}
Run Code Online (Sandbox Code Playgroud)
这改变了返回值,我得到了一个Set[None],这不是我想要的。
import util.chaining._
someMethodThatReurnsTheSet
.partition(_.isRight)
.tap { case (_, lefts) => logger.warn(s"Bad objects $lefts") }
.pipe { case (rights, _) => rights }
Run Code Online (Sandbox Code Playgroud)
简单的方法:
someMethodThatReurnsTheSet().collect {
case Right(value) => Some(value)
case Left(res) =>
logger.warn(s"Bad object : $res")
None
}.flatten
Run Code Online (Sandbox Code Playgroud)
许多替代方案都是可能的,例如或查看其他答案:)
val (lefts, rights) = someMethodThatReurnsTheSet().partition(_.isLeft)
lefts.foreach(err => logger.warn(s"Bad object : ${err.left.get}"))
val set = rights.map(_.right.get)
Run Code Online (Sandbox Code Playgroud)
另一种使用方式foldLeft:
someMethodThatReturnsTheSet.foldLeft(Set.empty[GoodObject]) {
case (acc, goodOrBad) => goodOrBad match {
case Right(good) => acc + good
case Left(bad) =>
logger.warn("Bad object: $bad")
acc
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不介意分配:
someMethodThatReturnsTheSet.flatMap {
case Right(good) => Set(good)
case Left(bad) =>
logger.warn("Bad object: $bad")
Set.empty
}
Run Code Online (Sandbox Code Playgroud)