你好,我是小必,感謝與你在這裡相遇。
今日內容:迴圈遞迴函式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 LoopEnd 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 LoopEnd 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 LoopEnd Sub