gpt4 book ai didi

scala - 如何使用 Scala 惰性集合实现 takeUntil

转载 作者:行者123 更新时间:2023-12-03 08:59:38 28 4
gpt4 key购买 nike

我有一个昂贵的函数,我希望在满足以下要求的情况下运行尽可能少的次数:

  • 我有几个输入值要尝试
  • 如果函数返回低于给定阈值的值,我不想尝试其他输入
  • 如果没有结果低于阈值,我想以最小的输出获取结果

我无法使用迭代器的 takeWhile/dropWhile 找到一个好的解决方案,因为我想包含第一个匹配元素。最后得到了以下解决方案:

val pseudoResult = Map("a" -> 0.6,"b" -> 0.2, "c" -> 1.0)

def expensiveFunc(s:String) : Double = {
pseudoResult(s)
}

val inputsToTry = Seq("a","b","c")

val inputIt = inputsToTry.iterator
val results = mutable.ArrayBuffer.empty[(String, Double)]

val earlyAbort = 0.5 // threshold

breakable {
while (inputIt.hasNext) {
val name = inputIt.next()
val res = expensiveFunc(name)
results += Tuple2(name,res)
if (res<earlyAbort) break()
}
}

println(results) // ArrayBuffer((a,0.6), (b,0.2))

val (name, bestResult) = results.minBy(_._2) // (b, 0.2)

如果我设置 val EarlyAbort = 0.1,结果仍应为 (b, 0.2),而无需再次评估所有情况。

最佳答案

您可以利用Stream来实现您正在寻找的内容,请记住Stream是某种惰性集合,它按需评估操作。

这是 scala Stream文档。

您只需执行以下操作:

val pseudoResult = Map("a" -> 0.6,"b" -> 0.2, "c" -> 1.0)
val earlyAbort = 0.5

def expensiveFunc(s: String): Double = {
println(s"Evaluating for $s")
pseudoResult(s)
}

val inputsToTry = Seq("a","b","c")

val results = inputsToTry.toStream.map(input => input -> expensiveFunc(input))
val finalResult = results.find { case (k, res) => res < earlyAbort }.getOrElse(results.minBy(_._2))

如果find没有得到任何值,你可以使用相同的流来查找最小值,并且函数不会再次计算,这是因为记忆化:

The Stream class also employs memoization such that previously computed values are converted from Stream elements to concrete values of type A

请考虑,如果原始集合为空,此代码将会失败,如果您想支持空集合,您应该将 minBy 替换为 sortBy(_._2).headOptionorElsegetOrElse:

val finalResultOpt = results.find { case (k, res) => res < earlyAbort }.orElse(results.sortBy(_._2).headOption)

其输出是:

评估

评估 b

最终结果:(字符串, double )=(b,0.2)

finalResultOpt:选项[(String, Double)] = Some((b,0.2))

关于scala - 如何使用 Scala 惰性集合实现 takeUntil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51768030/

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