fold 方法使用初始累加器值迭代一个集合,并应用一个使用每个元素成功更新累加器的函数:

val nums = List(1,2,3,4,5)
var initialValue:Int = 0;
var sum = nums.fold(initialValue){
  (accumulator,currentElementBeingIterated) => accumulator + currentElementBeingIterated
}
println(sum) //prints 15 because 0+1+2+3+4+5 = 15

在上面的例子中,向 fold() 提供了一个匿名函数。你还可以使用带有两个参数的命名函数。在我看来,上面的例子可以重写如下:

def sum(x: Int, y: Int) = x+ y
val nums = List(1, 2, 3, 4, 5)
var initialValue: Int = 0
val sum = nums.fold(initialValue)(sum)
println(sum) // prints 15 because 0 + 1 + 2 + 3 + 4 + 5 = 15

更改初始值将影响结果:

initialValue = 2;
sum = nums.fold(initialValue){ 
 (accumulator,currentElementBeingIterated) => accumulator + currentElementBeingIterated
}
println(sum) //prints 17 because 2+1+2+3+4+5 = 17

fold 方法有两个变体 - foldLeftfoldRight

foldLeft() 从左到右迭代(从集合的第一个元素到该顺序的最后一个元素)。foldRight() 从右到左迭代(从最后一个元素到第一个元素)。fold()foldLeft() 一样从左到右迭代。实际上,fold() 实际上是在内部调用 foldLeft()

def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)

fold()foldLeft()foldRight() 将返回与其所需的初始值具有相同类型的值。但是,与 foldLeft()foldRight() 不同,fold() 的初始值只能是同一类型或集合类型的超类型。

在此示例中,顺序不相关,因此你可以将 fold() 更改为 foldLeft()foldRight(),结果将保持不变。使用对订单敏感的功能将改变结果。

如果有疑问,请选择 foldLeft() 而不是 foldRight()foldRight() 性能较差。