Scala 中的 fold 函数

折叠和反折叠(Folding and unfolding)

我们这里只讨论 floding,来自于 wikipedia 的 folding 的定义:

在函数式编程中,fold - 同样被称为reduce,accumulate,aggregate,compress或者inject -是指一类高阶函数,它们通过递归调用给定的合并操作来处理递归的数据结构并返回最终的结果

大体上,你输入一些数据,应用一个方法并且返回不同的值。让我们看一下fold的方法签名:

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

用二元合并操作对traversableiterator的元素进行折叠。对元素操作的执行顺序是不明确的也可能每次操作的执行顺序都不同。

  • A1:二元操作的一个类型参数,是A类型的父类
  • z:对于fold操作来说中立的元素;可能会任意次数增加到结果中,必须确保不影响结果。(比如,Nil对于列表链接操作,0对于加法操作,或1对于乘法操作)
  • op:一个二元合并操作
  • 返回:将fold操作op应用在所有元素和z间的结果。

来看一个例子

val list = "Hello World this is a string".split(" ")
val res = list.fold("scala")((z, i) => z + ":" + i)
println(res) // scala:Hello:World:this:is:a:string

我们可以知道 第一个参数 z 是起始值,类型必须大于等于集合中的类型,然后按照第二个参数 op 的函数类容进行操作,将新的值赋给 z ,然后进行下一次递归

再来看一个例子,求和

val list = List.range(0, 10) // [0,10)
val res = list.fold(0)((z, i) => z + i)
println(res) // 45

这里可以简化

val res = list.fold(0)(_ + _)

求乘积

list.fold(1)(_ * _)

求 count, 这里必须声明一个 sum,因为 _ + 1 有歧义, 能求和是因为集合也是 Int,flodLeft 没有这个限制

list.fold(0)((sum, _) => sum + 1)


- - - - - - - - End Thank For Your Reading - - - - - - - -