你好,我是小必,感谢与你在这里相遇。
今日内容:循环递归函数List.Accumulate函数。
在Power Query中,List.Accumulate函数是一个高阶函数,同时也是一个很重要的函数。学习List.Accumultae函数,说明你的Power Query的M语言已经进入到了一个比较深的阶段了。这个函数是也是M语言中高难度的函数之一,但是很有用。
由于M是函数语言,这个里面是没有循环类的语言,如VBA中的for语句,或者do loop之类的。所以这个函数的功能也很简单,就是循环。
先来看一下官方给出的函数的解释与语法。从下面的这个语法说明中,着实没有看明白这个函数是干什么用的。
简单来说,这个函数的语法,可以写个如下:
List.Accumulate(
迭代运算参考列表,
迭代初始值,
根据迭代运算参考列表进行迭代运算
)
第一个参数迭代运算参考列表的类型是一个List;第二个迭代的初始值可以是list,record,文本,table等等;第三个参数就是迭代运算部分。
案例1
先看一下简单的例子:求1到9的累计的和。
= List.Accumulate({1..9},0,(x,y)=>x+y)
此时的公式可以写成这样:List.Accululate是需要自定义的,对于循环来说,需要先定一个容器用来放结果,还需要相应的循环变量,那么就List.Accumulate的第二个参数,这个公式中定的循环是一个数字,初始值为0,(x,y)=>这一部分中的x,y是指代的变量,即x为第二个参数,y为第一个参数中的每个元素。来看一下循环:
初始值为第二个参数即0,循环运算为将迭代的参考值与进行累加。
第1次循环:初始值为0,即x=0,y={1..9}{0}的第一个元素,即为1,所以x+y=1;
第2次循环:初始值为上一次循环中执行的x+y=1,即x=1,y={1..9}{}1的第二个元素,即为2,所以x=y=1+2=3;
……
最后一次循环,初始值为x=0+1+2+3+4+5+6+7+8=36,y={1..9}{8}的第9个元素,即为9,所以x+y=36+9=45.
最终返回的结果为45.
案例2
上面的例子只是返回一个累加的数字,所以难度再提升一下:计算{1..9}的累加合计,返回一个与list同样尺寸的list。
先看一下代码:
= List.Accumulate({1..9},{},(x,y)=>x&{List.Sum({List.Last(x),y})})
相比较上面的入门的例子,这个例子就相对来说比较复杂了。首先定一个容器,即为一个list,且为空list,如{},即没有任何一个元素。List.Last是返回一个列表中的最后一个元素,List.Sum是对列表进行求和。
这个里面{List.Last(x),y}List.Last返回的是一个元素,即数值,y也是{1..9}中的数值,而此时的x是一个列表,即{},所以在合并的时候对于List.Last(x)与y外面套一个{}组成一个列表,而使用List.Sum求和后仍然是一个元素,还需要转化成列表,加一个{}即可。
第1次循环:初始值为{},即x={},y={1..9}{0}的第1个元素,即y=1.此时x&{List.Sum({List.Last(x),y})}={}&{1},即{1}。
第2次循环:初始值为{1},即x={1},y={1..9}{1}的第2个元素,即y=2.此时x&{List.Sum({List.Last(x),y})}={1}&{3},即{1,3}。
第3次循环:初始值为{1,3},即x={1,3},y={1..9}{2}的第3个元素,即y=3.此时x&{List.Sum({List.Last(x),y})}={1,3}&{6},即{1,3,6}。
……
最后1次循环:初始值为{1,3,6,10,15,21,28,36},即x={1,3,6,10,15,21,28,36},y={1..9}{8}的第9个元素,即y=9.此时x&{List.Sum({List.Last(x),y})}={1,3,6,10,15,21,28,36}&{45},即{1,3,6,10,15,21,28,36,45}。
拓展
需要注意的是这个函数的第3个参数是(x,y)=>是固定的写法,x与y可以替换成任意的变量。
为了方便大家与VBA中的循环语句进行对比,现贴出VBA代码,以便用来对比学习。
Sub 累加()
Dim i As Integer
i = 2
Do While Cells(i, 1) <> ""
s = s + Cells(i, 1)
Cells(i, 2) = s
i = i + 1
Loop
End Sub
Sub l累加2()
Dim i As Integer
i = 2
Do
If Cells(i, 1) = "" Then
Exit Sub
Else
s = s + Cells(i, 1)
Cells(i, 2) = s
End If
i = i + 1
Loop
End Sub
Sub 累加3()
Dim i As Integer
i = 2
Do Until Cells(i, 1) = ""
s = s + Cells(i, 1)
Cells(i, 2) = s
i = i + 1
Loop
End Sub