使用日志记录过滤一组 Either[x, y]
Filtering a set of Either[x, y], with logging
给定 Set[Either[BadObject, GoodObject]]
,我想将其转换为 Set[GoodObject]
,同时记录所有 BadObjects
。
我遇到的问题是,当我尝试在 collect
调用中添加登录时,例如:
someMethodThatReurnsTheSet.collect {
case Right(value) => value
case Left(res) => logger.warn(s"Bad object : $res")
}
这会更改 return 值,我得到 Set[None]
,这不是我想要的。
简单方法:
someMethodThatReurnsTheSet().collect {
case Right(value) => Some(value)
case Left(res) =>
logger.warn(s"Bad object : $res")
None
}.flatten
很多替代方案都是可能的,例如或查看其他答案:)
val (lefts, rights) = someMethodThatReurnsTheSet().partition(_.isLeft)
lefts.foreach(err => logger.warn(s"Bad object : ${err.left.get}"))
val set = rights.map(_.right.get)
使用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
}
}
如果您不介意分配:
someMethodThatReturnsTheSet.flatMap {
case Right(good) => Set(good)
case Left(bad) =>
logger.warn("Bad object: $bad")
Set.empty
}
尝试partition
in combination with chaining
import util.chaining._
someMethodThatReurnsTheSet
.partition(_.isRight)
.tap { case (_, lefts) => logger.warn(s"Bad objects $lefts") }
.pipe { case (rights, _) => rights }
如果你只想在Left
情况下采取行动,你可以使用.left.foreach
:
setOfEithers.flatMap { e =>
e.left.foreach { bad => logger.warn(s"Bad object: $bad") }
e.toOption
}
给定 Set[Either[BadObject, GoodObject]]
,我想将其转换为 Set[GoodObject]
,同时记录所有 BadObjects
。
我遇到的问题是,当我尝试在 collect
调用中添加登录时,例如:
someMethodThatReurnsTheSet.collect {
case Right(value) => value
case Left(res) => logger.warn(s"Bad object : $res")
}
这会更改 return 值,我得到 Set[None]
,这不是我想要的。
简单方法:
someMethodThatReurnsTheSet().collect {
case Right(value) => Some(value)
case Left(res) =>
logger.warn(s"Bad object : $res")
None
}.flatten
很多替代方案都是可能的,例如或查看其他答案:)
val (lefts, rights) = someMethodThatReurnsTheSet().partition(_.isLeft)
lefts.foreach(err => logger.warn(s"Bad object : ${err.left.get}"))
val set = rights.map(_.right.get)
使用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
}
}
如果您不介意分配:
someMethodThatReturnsTheSet.flatMap {
case Right(good) => Set(good)
case Left(bad) =>
logger.warn("Bad object: $bad")
Set.empty
}
尝试partition
in combination with chaining
import util.chaining._
someMethodThatReurnsTheSet
.partition(_.isRight)
.tap { case (_, lefts) => logger.warn(s"Bad objects $lefts") }
.pipe { case (rights, _) => rights }
如果你只想在Left
情况下采取行动,你可以使用.left.foreach
:
setOfEithers.flatMap { e =>
e.left.foreach { bad => logger.warn(s"Bad object: $bad") }
e.toOption
}