累计结果直到某些条件以功能方式得到满足

时间:2013-11-12 18:37:34

标签: scala functional-programming

我在循环中有一些昂贵的计算,我需要找到计算产生的最大值,但是,如果它等于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集合库中?

更新:Do something up to N times or until condition is met in Scala - 有一个有趣的想法(使用懒惰并在最后找到或存在)但它不能直接应用于我的特定情况或需要mutable var来跟踪累加器。

1 个答案:

答案 0 :(得分:3)

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

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

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

更新

根据您的评论,我尝试根据LinearSeqOptimized的foldLeft实现调整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)
}

您可能会使用implicits省略list的第一个参数。 希望这会有所帮助。