3

我在一个循环中有一些昂贵的计算,我需要找到计算产生的最大值,但如果它等于 LIMIT 我想停止计算并返回我的累加器。

它可以很容易地通过递归来完成:

val list: List[Int] = ???
val UpperBound = ???

def findMax(ls: List[Int], max: Int): Int = ls match {
  case h :: rest =>
    val v = expensiveComputation(h)
    if (v == UpperBound) v
    else findMax(rest, math.max(max, v))

  case _ => max
}

findMax(list, 0)

我的问题:此行为模板是否有名称并反映在 scala 集合库中?

更新:在 Scala 中最多执行 N 次或直到满足条件- 有一个有趣的想法(使用惰性并在最后找到或存在)但它并不直接适用于我的特定情况或需要可变 var 来跟踪累加器。

4

1 回答 1

4

我认为你的递归函数非常好,所以老实说我不会改变它,但这里有一种使用集合库的方法:

list.foldLeft(0) {
  case (max, next) =>
    if(max == UpperBound)
      max
    else
      math.max(expensiveComputation(next), max)
}

它将遍历整个列表,但在达到上限后,它不会执行昂贵的计算。

更新

根据您的评论,我尝试根据LinearSeqOptimizedfoldLeft 实现稍微调整 foldLeft。

def foldLeftWithExit[A, B](list: Seq[A])(z: B)(exit: B => Boolean)(f: (B, A) => B): B = {
  var acc = z
  var remaining = list
  while (!remaining.isEmpty && !exit(acc)) {
    acc = f(acc, list.head)
    remaining = remaining.tail
  }
  acc
}

调用它:

foldLeftWithExit(list)(0)(UpperBound==){
  case (max, next) =>  math.max(expensiveComputation(next), max)
}

您可能会使用隐式来省略list. 希望这可以帮助。

于 2013-11-12T19:56:54.580 回答