【发布时间】:2018-08-09 13:13:55
【问题描述】:
我有一个昂贵的函数,我想尽可能少地运行它,满足以下要求:
- 我有几个输入值要尝试
- 如果函数返回的值低于给定阈值,我不想尝试其他输入
- 如果没有结果低于阈值,我想以最小输出取结果
我找不到使用 Iterator 的 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),而无需再次评估所有案例。
【问题讨论】:
-
def takeUntil[A](it: Iterator[A])(p: A => Boolean): Iterator[A] = it.takeWhile(!p(_)) -
@stefanobaghino 我看不出这有什么帮助,你能用我的测试用例分享一个完整的答案吗?
标签: scala lazy-sequences