Scala:如何解释 foldLeft

Scala: How to interpret foldLeft

我有两个例子foldLeft,我无法真正理解其中的逻辑。

第一个例子:

val donuts: List[String] = List("Plain", "Strawberry", "Glazed")
println(donuts.foldLeft("")((acc, curr) =>  s" $acc, $curr Donut ")) // acc for accumulated, curr for current

这会给

 , Plain Donut , Strawberry Donut , Glazed Donut

foldLeft积累之前的价值吗? 我期待的结果是

 , Plain Donut ,  Plain Strawberry Donut , Strawberry Glazed Donut

第二个例子:

def multi(num:Int,num1:Int):Int=num*10

(1 until 3).foldLeft(1)(multi)

谁能解释一下每一步发生了什么?我看不出这怎么会变成 100。另外,第二个参数 multi 是一个函数。为什么它不接受任何输入变量(num 和 num1)?

Does not foldLeft accumulate value that was earlier?

是的。它 uses 先前迭代和当前元素的结果并产生新结果(使用您提供的二元运算符)因此对于第一个示例,接下来的步骤正在发生:

  1. 累加器起始值 - ""

  2. acc = "", curr = "Plain" -> " , Plain Donut "

  3. acc = " , Plain Donut ", curr = "Strawberry" -> " , Plain Donut , Strawberry Donut "

  4. acc = " , Plain Donut , Strawberry Donut ", curr = "Strawberry" -> " , Plain Donut , Strawberry Donut , Glazed Donut"

对于第二个示例,当前值被简单地忽略 - 即 multi 可以重写为 def multi(acc:Int, curr:Int):Int = acc*10,其中 curr 实际上并未使用,因此 foldLeft 简单地乘以起始值(1) 乘以 10 n 次,其中 n 是序列中元素的数量(即 (1 until 3).length 为 2)。

Why does it not take any input variables (num and num1)?

foldLeft is a function which accepts a function。它接受 generic 函数依次接受两个参数和与第一个参数类型相同的 returns 结果(op: (B, A) => B,其中 B 是结果类型,A 是序列元素类型)。当 B == A == Intmulti 匹配此定义并传递给 foldLeft ,后者将在每个步骤内部提供输入变量。

左折叠需要三样东西:要处理的列表、初始值和函数。

该函数获取列表中的每个元素并将其应用于初始值。每次的初始值都是上一次函数应用的结果

总结列表是一个很好的玩具示例。

val nums = List(1, 2, 3, 4)
val total = nums.foldLeft(0)((a, b) => a + b)

total10

该初始值必须通过您需要的所有状态。目前,您传递了累积的字符串。你应该传递的是一个 tuple 给你的函数额外的信息来处理:累积的字符串,和一个代表 previous 元素的字符串列表。

您的结果将类似于:

("Plain donut, ...", "Glazed")

那么你只需要select取出累积的字符串并丢弃第二个元素。