过滤 Scala Either 列表中的失败
Filtering a Scala Either list for failures
我有一个输入值列表
List[A]
和一个函数
f(List[A]): Either[Failure, Success]
我将函数应用于列表的每个元素,结果是 List[Either[Failure, Success]]
。
我想检查列表,如果有任何值失败,return 第一次失败,否则 return 成功列表。
我使用了以下模式:
val allValues = list.map(f(_))
if (allValues.exists(_.isLeft)) {
allValues.find(_.isLeft).get
} else {
allValues.collect {
case Right(result) => result
}
}
和
val allValues = list.map(f(_))
val failures = allValues.collect { case Left(error) => error }
if (failures.nonEmpty) {
failures(0)
} else {
allValues.collect {
case Right(result) => result
}
}
有没有更简洁的表达方式?
有时,我必须通过另一个函数进一步处理成功,再次使用相同的模式。例如
- 将 JSON 数组转换为 Scala 模型,如果任何 JSON 对象格式不正确则失败。
- 将模型写入数据库,如果任何数据库更新失败则失败。
这应该有效
l.collectFirst { case Left(error) => error }.getOrElse {
l.map(_.right)
}
其中 l
是 Either[Left, Right]
的列表
例如:
万一出现错误
val l = List(Right(1), Right(2), Left(3), Left(4), Right(5))
l.collectFirst { case Left(error) => error }.getOrElse {
l.map(_.right)
} //res0: Any = 3
它 returns any
因为它可以 return Failure
或 Success
的列表
听起来好像您想将 List[Either[Failure, Success]]
转换为 Either[Failure, List[Success]]
?您可以使用 toLeft
.
使它更优雅
result collectFirst { case Left(f) => f } toLeft {
result collect { case Right(r) => r}
}
collectFirst
接受一个 PartialFunction[A, B]
它将应用于 List
的具有定义输出的第一个元素,并将 return Option[B]
.在这种情况下,我尝试从 List
中提取第一个 Left(f)
,因此我将得到 Option[Failure]
.
然后,我在 Option[Failure]
上调用 toLeft
。如果 Option
包含一个值,这将再次将单个 Failure
转换为 Left
,如果 Option
为空,则参数将生成 Right
值。
如果 Option
确实为空,那么我使用 collect
提取成功,类似于使用 collectFirst
,只是它保留了 List
的所有元素PartialFunction
是为
定义的
我有一个输入值列表
List[A]
和一个函数
f(List[A]): Either[Failure, Success]
我将函数应用于列表的每个元素,结果是 List[Either[Failure, Success]]
。
我想检查列表,如果有任何值失败,return 第一次失败,否则 return 成功列表。
我使用了以下模式:
val allValues = list.map(f(_))
if (allValues.exists(_.isLeft)) {
allValues.find(_.isLeft).get
} else {
allValues.collect {
case Right(result) => result
}
}
和
val allValues = list.map(f(_))
val failures = allValues.collect { case Left(error) => error }
if (failures.nonEmpty) {
failures(0)
} else {
allValues.collect {
case Right(result) => result
}
}
有没有更简洁的表达方式?
有时,我必须通过另一个函数进一步处理成功,再次使用相同的模式。例如
- 将 JSON 数组转换为 Scala 模型,如果任何 JSON 对象格式不正确则失败。
- 将模型写入数据库,如果任何数据库更新失败则失败。
这应该有效
l.collectFirst { case Left(error) => error }.getOrElse {
l.map(_.right)
}
其中 l
是 Either[Left, Right]
例如:
万一出现错误
val l = List(Right(1), Right(2), Left(3), Left(4), Right(5))
l.collectFirst { case Left(error) => error }.getOrElse {
l.map(_.right)
} //res0: Any = 3
它 returns any
因为它可以 return Failure
或 Success
听起来好像您想将 List[Either[Failure, Success]]
转换为 Either[Failure, List[Success]]
?您可以使用 toLeft
.
result collectFirst { case Left(f) => f } toLeft {
result collect { case Right(r) => r}
}
collectFirst
接受一个 PartialFunction[A, B]
它将应用于 List
的具有定义输出的第一个元素,并将 return Option[B]
.在这种情况下,我尝试从 List
中提取第一个 Left(f)
,因此我将得到 Option[Failure]
.
然后,我在 Option[Failure]
上调用 toLeft
。如果 Option
包含一个值,这将再次将单个 Failure
转换为 Left
,如果 Option
为空,则参数将生成 Right
值。
如果 Option
确实为空,那么我使用 collect
提取成功,类似于使用 collectFirst
,只是它保留了 List
的所有元素PartialFunction
是为