在Scala中实现foldLeft

vzgqcmou  于 2022-11-23  发布在  Scala
关注(0)|答案(3)|浏览(164)

TraversableOnce使用可变的var result实现foldLeft

def foldLeft[B](z: B)(op: (B, A) => B): B = {
   var result = z
   this foreach (x => result = op(result, x))
   result
}

我知道递归地实现foldLeft是不实际的,现在我想知道是否有可能在没有可变变量的情况下高效地实现foldLeft
能做到吗?如果不能,为什么?

sqyvllje

sqyvllje1#

尾递归是您的朋友:

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没有实现headtail,访问这些元素的唯一方法是使用foreach

ax6ht2ek

ax6ht2ek2#

object FoldImplement:
  def myFoldLeft(lst: List[Int])(acc: Int)(f: (Int, Int)=>Int): Int =
    lst match
      case List() => acc
      case hd::tl => myFoldLeft(tl)(f(hd,acc))(f)

  @main def runFoldImpl =
    println(myFoldLeft(List(1,3,5))(0)((acc,elem)=>acc+elem))
cbeh67ev

cbeh67ev3#

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)
}

相关问题