【问题标题】:Convert Iterable[Try[U]] to Try[Iterable[U]] in Scala [duplicate]在Scala中将Iterable [Try [U]]转换为Try [Iterable [U]] [重复]
【发布时间】:2021-01-19 17:11:07
【问题描述】:

如何将 Iterable 的 Try 值转换为 Iterable 的 Try? 如果 Iterable 包含失败,则应返回第一个失败,如果没有失败则返回应返回可迭代的 Success 值。

例如,假设转换函数被称为squash:

import scala.util.{Try, Success, Failure}

def squash[U](iterable : Iterable[Try[U]]) : Try[Iterable[U]] = ???

包含失败的 Iterable 的预期行为:

val containsFailure : Iterable[Try[Int]] = 
  Iterable[Try[Int]](Success(42), Failure(new Exception("foo")), Success(43), Failure(new Exception("bar")))

assert(squash(containsFailure) ==  Failure(new Exception("foo")))

以及没有失败的 Iterable 的预期行为:

val noFailures : Iterable[Try[Int]] = 
  Iterable[Try[Int]](Success(42), Success(43), Success(44))

assert(squash(noFailures) == Success(Iterable(42,43,44)))

我正在寻找仅包含标准 scala 功能的解决方案,请不要将 scalaz 或 cats 等库作为答案的一部分。

提前感谢您的考虑和回复。

【问题讨论】:

标签: scala


【解决方案1】:

与问题中发布的个人资料保持一致。

import scala.util.{Try, Success, Failure}

def squash[U](iterable : Iterable[Try[U]]) : Try[Iterable[U]] =
  iterable.foldLeft(Try(Iterable.empty[U])){
    case (Success(a),Success(b)) => Success(a ++ Iterable(b))
    case (Success(_),Failure(ex)) => Failure(ex)
    case (failed, _) => failed
  }

【讨论】:

    【解决方案2】:

    返回Seq 而不是Iterable 的解决方案:

    def squash[U](iterable : Iterable[Try[U]]): Try[Seq[U]] =
      iterable.foldLeft[Try[Vector[U]]](Success(Vector.empty[U]))((result: Try[Vector[U]], t: Try[U]) =>
        result flatMap (vector => t match {
          case Failure(ex) => Failure[Vector[U]](ex)
          case Success(value) => Success(vector :+ value)
        }))
    

    【讨论】:

      猜你喜欢
      • 2015-06-30
      • 2010-11-07
      • 2016-01-21
      • 2013-06-01
      • 2019-03-15
      • 2012-01-04
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多