gpt4 book ai didi

Scala - try-catch inside for loop with yield

转载 作者:行者123 更新时间:2023-12-04 15:44:10 28 4
gpt4 key购买 nike

我正在使用一些第 3 方库编写 Scala 应用程序。迭代该库中的集合时发生异常,我想忽略它并继续迭代。整个过程都在带有 yield 的 for 循环中。

val myFuntionalSequence = for {
mailing <- mailingCollection
} yield (mailing.getName, mailing.getSubject)

如前所述,错误发生在迭代内部,所以这一行:

mailing <- mailingCollection

如果我在整个循环中放置一个 try catch,那么我将无法继续迭代。我有一个非功能性解决方案,具有与上述相同的输出,但我想使整个应用程序保持功能性风格。这是我以非功能性方式提出的:

case class MyElement(name: String, subject: String)

...

var myNonFunctionalList = scala.collection.mutable.ListBuffer[MyElement]()

while(mailingIterator.hasNext) {
try {
val mailing = mailingIterator.next()
myNonFunctionalList += MyElement(mailing.getName, mailing.getSubject)
} catch {
case e: Exception => println("Error")
}
}

我的问题是,您是否知道尝试迭代 for 循环并在出错时跳过该元素并仅返回迭代有效的元素的函数式方法?

谢谢,菲利克斯

最佳答案

如果你想保持功能,那么你需要一个递归函数来取消选择不可靠的迭代器。

这是未经测试的代码,但它可能看起来像这样:

def safeIterate[T](i: Iterator[T]): List[Try[T]] = {
@annotation.tailrec
def loop(res: List[Try[T]]): List[Try[T]] =
if (i.hasNext) {
loop(Try(i.next) +: res)
} else {
res.reverse
}

loop(Nil)
}

您可以检查每个 Try 值以查看哪些迭代成功或失败。如果您只想要成功值,那么您可以在 List 上调用 .flatMap(_.toOption)。或者使用这个版本的 safeIterate:

def safeIterate[T](i: Iterator[T]): List[T] = {
@annotation.tailrec
def loop(res: List[T]): List[T] =
if (i.hasNext) {
Try(i.next) match {
case Success(t) => loop(t +: res)
case _ => loop(res)
}
} else {
res.reverse
}

loop(Nil)
}

比我聪明的人可能会返回另一个 Iterator 而不是 List

关于Scala - try-catch inside for loop with yield,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56597876/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com