foldLeft在Scala中的实现
使用可变的foldLeft在Scala中的实现,scala,collections,fold,Scala,Collections,Fold,使用可变的var结果实现foldLeft def foldLeft[B](z: B)(op: (B, A) => B): B = { var result = z this foreach (x => result = op(result, x)) result } 我理解递归实现foldLeft是不实际的。现在我想知道是否有可能在没有可变变量的情况下高效地实现foldLeft 能做到吗?如果不能,为什么?尾部递归是你的朋友: def foldLeft[A, B]
var结果实现foldLeft
def foldLeft[B](z: B)(op: (B, A) => B): B = {
var result = z
this foreach (x => result = op(result, x))
result
}
我理解递归实现foldLeft
是不实际的。现在我想知道是否有可能在没有可变变量的情况下高效地实现foldLeft
能做到吗?如果不能,为什么?尾部递归是你的朋友:
def foldLeft[A, B](xs: Seq[A], z: B)(op: (B, A) => B): B = {
def f(xs: Seq[A], acc: B): B = xs match {
case Seq() => acc
case x +: xs => f(xs, op(acc, x))
}
f(xs, z)
}
顺便说一句,TraversableOnce
不实现head
或tail
,访问元素的唯一方法是使用foreach
除非集合是列表
,否则toList
操作需要O(n)
。因此,这是一个低效的解决方案。因此foldLeft仍然是O(n):p,就像sschaef所说的,在transversableOnce
内部,访问元素的唯一方法是foreach
,所以当您真的想递归地执行时,您将不得不失去一些效率……因此,这个问题的完整答案是:可以以最有效的方式实现不带可变变量的foldLeft
,但不能以TraversableOnce
实现,因为缺少O(1)
head和tail函数。您可能应该将其添加到您的答案中。使用toIterator
时,开销不应该更低吗?
def foldLeft[B](z: B)(op: (B, A) => B): B = {
val thislist = this.toList
@tailrec
def myFold(result: B, list: List[A]): B = list match {
case Nil => result
case head :: tail => myFold(op(result,head), tail)
}
myFold(z, thislist)
}