HI,大家好,我是星光。
近幾年來(lái),Excel函數(shù)做了兩次變革。第1次變革是動(dòng)態(tài)數(shù)組,極大提高了函數(shù)的計(jì)算效率,它的核心函數(shù)是FILTER。第2次變革是編程式函數(shù)體系,用編程的方式分步驟編寫函數(shù),用顯性循環(huán)替代之前的數(shù)組運(yùn)算。
這批函數(shù)包含了我們之前分享過(guò)的LET/SCAN/BYROW/MAP/VSTACK等等,它們也有一個(gè)核心函數(shù),就是今天要給大家分享的REDUCE。
▎基礎(chǔ)語(yǔ)法
REDUCE函數(shù)只有3個(gè)參數(shù),看起來(lái)簡(jiǎn)單而單純。
=REDUCE([initial_value], array,
lambda(accumulator, value))
第1個(gè)參數(shù)是初始累加值,第2個(gè)參數(shù)是源數(shù)組,第3個(gè)參數(shù)是LAMBDA表達(dá)式自定義計(jì)算方式,它又有兩個(gè)參數(shù),其中acc指向'初始累加值',value指向源數(shù)組每個(gè)被遍歷的元素。
先舉一個(gè)簡(jiǎn)單的例子,給大家演示下該函數(shù)的計(jì)算過(guò)程。
如上圖所示的數(shù)據(jù)表,A列是班級(jí)、B列是姓名。假設(shè),現(xiàn)在需要統(tǒng)計(jì)1班的人數(shù),REDUCE的解法如下:
=REDUCE(0,A2:A8,
LAMBDA(_p,_v,
IF(_v='1班',_p+1,_p)
)
)
REDUCE第1參數(shù)為0,表示初始值為0,第2參數(shù)為A2:A8,第3參數(shù)是一個(gè)LAMBDA表達(dá)式,有兩個(gè)參數(shù)_p和_v,其中_p作為初始值,目前為0,_v指向REDUCE的第2參數(shù),即A2:A8。
LAMBDA遍歷A2:A8每一個(gè)值,運(yùn)行表達(dá)式IF(_v='1班',_p+1,_p)。
A2單元格為1班,則條件成立,返回結(jié)果_p+1,即0+1,結(jié)果為1,作為L(zhǎng)AMBDA新的第1參數(shù),也就是新的初始值。
A3單元格為1班,則條件成立,返回結(jié)果_p+1,即1+1,結(jié)果為2,作為L(zhǎng)AMBDA新的第1參數(shù),也就是新的初始值。
A4單元格為2班,則條件不成立,返回結(jié)果_p,即2,作為L(zhǎng)AMBDA新的第1參數(shù)。
……
依次類推,直至遍歷完A2:A8的所有元素,將LAMBDA第1參數(shù)的值返回,結(jié)果為3?!绻阌蠱函數(shù)或者JS函數(shù)的學(xué)習(xí)經(jīng)驗(yàn),對(duì)該計(jì)算方式應(yīng)該是秒懂的。
以上的案例是條件計(jì)數(shù),同樣的道理,我們還可以用REDUCE解決條件查詢、條件求和等問(wèn)題。
REDUCE條件求和
統(tǒng)計(jì)1班成績(jī)總分: ▼
=REDUCE(0,ROW(2:8),
LAMBDA(_p,_v,
IF(
INDEX(A:A,_v)='1班',
_p+INDEX(D:D,_v),
_p
)
)
)
REDUCE條件查詢
查詢1班人員名單 ▼
=REDUCE('',ROW(2:8),
LAMBDA(_p,_v,
IF(
INDEX(A:A,_v)='1班',
_p&' ' &INDEX(B:B,_v),
_p
)
)
)
……
▎常用情景
打個(gè)響指,條件查詢/求和/計(jì)數(shù)這些常見(jiàn)問(wèn)題,Excel都封裝了專門的函數(shù),比如COUNTIF/SUMIF/TEXTJOIN等,在單值查詢的情況下,并不需要使用REDUCE函數(shù),以上只是通過(guò)你熟悉的例子,來(lái)說(shuō)明REDUCE的計(jì)算過(guò)程。
最常使用REDUCE函數(shù)的情景有兩種,一種是必須借助該函數(shù)的特性去解決的問(wèn)題,另外一種還是借助該函數(shù)的特性,以動(dòng)態(tài)數(shù)組的形式,用一條函數(shù)公式,實(shí)現(xiàn)多值數(shù)據(jù)計(jì)算,這可以極大提高函數(shù)的計(jì)算效率。
先看第1種情景,我舉2個(gè)典型的案例。
1)多表匯總
如下圖所示,有3張工作表,名稱分別為一月、二月、三月,現(xiàn)在需要將3張表的數(shù)據(jù)合并成一張總表。
REDUCE解法如下:
公式看不全可以左右拖動(dòng)..
=REDUCE(
{'班級(jí)','姓名','成績(jī)'},
{'一月','二月','三月'},
LAMBDA(_p,_v,
VSTACK(_p,
DROP(
INDIRECT(_v&'!a1:c' & COUNTA(INDIRECT(_v&'!a:a'))),1)
)
)
)
REDUCE第1參數(shù)是標(biāo)題行,第2參數(shù)是需要合并的工作表的表名。LAMBDA表達(dá)式遍歷每張工作表,使用INDIRECT函數(shù)獲取相關(guān)工作表的實(shí)際數(shù)據(jù)區(qū)域,再使用DROP函數(shù)刪除重復(fù)的標(biāo)題行,最后使用VSTACK函數(shù)將新工作表的數(shù)據(jù)和累加值_p合并,實(shí)現(xiàn)多表數(shù)據(jù)合并的目的。
2)多重替換
如下圖所示,D:E是對(duì)照表,現(xiàn)在需要將A列數(shù)據(jù)中的舊數(shù)據(jù)替換為對(duì)應(yīng)的新數(shù)據(jù),比如,把A替換為福建,B替換為廣西等等。
B2單元格輸入以下REDUCE函數(shù)公式,向下復(fù)制填充:
=REDUCE(
A2,
$D$2:$D$5,
LAMBDA(_p,_v,
SUBSTITUTE(_p,_v,
VLOOKUP(_v,D:E,2,0)
)
)
)
LAMBDA遍歷REDUCE第2參數(shù)D2:D5中的每個(gè)值,將舊數(shù)據(jù)替換為VLOOKUP匹配的新數(shù)據(jù),不斷累加替換,直至將D2:D5單元格中每個(gè)舊數(shù)據(jù)都替換完畢,返回最后的累加值_p即可。
……
但這種在每個(gè)單元格都反復(fù)編寫函數(shù)公式的方式,會(huì)極大拖累函數(shù)的計(jì)算效率,它會(huì)反復(fù)將單元格區(qū)域的數(shù)據(jù),比如D2:E5,讀入內(nèi)存中執(zhí)行計(jì)算,再將計(jì)算結(jié)果多次寫入單元格中。
理想的計(jì)算方式是我們之前講過(guò)的動(dòng)態(tài)數(shù)組,用一次戰(zhàn)爭(zhēng)解決所有戰(zhàn)爭(zhēng),用一條函數(shù)公式,返回全部結(jié)果。這就是我們前面說(shuō)的REDUCE的第2種應(yīng)用場(chǎng)景了。
以多重替換案例來(lái)說(shuō),可以在B2單元格輸入以下動(dòng)態(tài)數(shù)組公式,直接返回全部結(jié)果:
=MAP(A2:A3,LAMBDA(_m,
REDUCE(_m,D2:D5,
LAMBDA(_p,_v,
SUBSTITUTE(_p,_v,
VLOOKUP(_v,D:E,2,0)
)))))
在上述公式中,我們?cè)赗EDUCE外又嵌套了個(gè)MAP函數(shù),用于遍歷A2:A3的數(shù)據(jù),并返回相應(yīng)的計(jì)算結(jié)果。
但MAP函數(shù)有一個(gè)強(qiáng)規(guī)則,它返回的結(jié)果數(shù)組和數(shù)據(jù)源數(shù)組的尺寸必然保持一致。而相比之下,REDUCE函數(shù)則自由的多,它并沒(méi)有這類限制,也就更適合搭配動(dòng)態(tài)數(shù)組高效解決問(wèn)題。
還是舉個(gè)例子。
如下圖所示,A列是由混合文本組成的數(shù)據(jù),需要從中提取班級(jí)、姓名、性別、語(yǔ)文、數(shù)學(xué)和英語(yǔ)等信息。C:H列是模擬結(jié)果。
函數(shù)參考解法如下:
=LET(
_n,{'班級(jí)','姓名','性別','語(yǔ)文','Math','EngLish'},
REDUCE(_n,A2:A3,LAMBDA(_p,_v,
VSTACK(_p,
IFNA(
VLOOKUP(_n,
TEXTSPLIT(_v,':',CHAR(10)),2,),
'查無(wú)')
)
)
)
)
函數(shù)首先定義了一個(gè)變量_n,內(nèi)容是標(biāo)題信息。
{'班級(jí)','姓名','性別','語(yǔ)文','Math','EngLish'}
然后使用REDUCE函數(shù)遍歷A2:A3。在遍歷過(guò)程中,使用TEXTSPLIT函數(shù)將數(shù)據(jù)按':'和換行符拆分為由項(xiàng)和內(nèi)容構(gòu)成的二維數(shù)組,比如A2單元格拆分結(jié)果如下:
使用VLOOKUP函數(shù),查詢標(biāo)題在以上二維數(shù)組中的值,如果查無(wú)結(jié)果,則返回字符串'查無(wú)'。這里返回的結(jié)果是一個(gè)水平一維數(shù)組:
將水平數(shù)組和REDUCE的初始值通過(guò)VSTACK函數(shù)縱向合并,得到一個(gè)新的初始值,結(jié)果如下:
然后再計(jì)算A3單元格,將計(jì)算結(jié)果和之前的初始值合并:
至此就將源數(shù)組所有元素遍歷完了,將LAMBDA第1參數(shù)作為結(jié)果返回。
攤手,就這么回事。
以上只是給大家介紹了下REDUCE各種用法中的極小且簡(jiǎn)單的部分,該函數(shù)除了用于數(shù)據(jù)查詢、統(tǒng)計(jì)、排名,也常用于數(shù)據(jù)整理、結(jié)構(gòu)轉(zhuǎn)換等等。你幾乎可以在任何復(fù)雜的函數(shù)問(wèn)題中見(jiàn)到它的身影。
更多REDUCE函數(shù)的實(shí)戰(zhàn)案例,可以參考我們的100道練習(xí)題系列,這個(gè)練習(xí)題系列的解法不但包含了工作表函數(shù),也包含了VBA/JS/PQ/PP/SQL以及Python等常用表格技術(shù)。
聯(lián)系客服