REDUCE 函数是动态数组中的“累积计算引擎”,它通过遍历数组中的每个元素,将初始值与当前元素依次传入自定义的 LAMBDA 函数进行运算,并将结果持续传递,最终将整个数组归约为一个单一的汇总值,适用于复杂的聚合统计场景。 REDUCE函数与SCAN类似,也可以设置一个累加器并遍历某个数组。但它只返回最终的汇总结果,而不是每一步的过程。比如,我们可以用它来计算一个区域内所有数的乘积,或者拼接一个字符串列表。REDUCE函数函数比SCAN函数功能更加强大。每次LAMBDA函数运算体运算完毕不仅可以返回单值,还可以返回数组,并且和已生成的累加器数组进行垂直方向或水平方向堆叠,因此REDUCE函数返回结果可以是单值或者多行列的数组。
函数语法结构为:
=REDUCE(initial, array, LAMBDA(acc, curr, calculation))
参数说明:
initial 初始累积值:计算的起点数值,为整个累积过程设定初始状态,决定了最终结果的初始基数。
array 要遍历的数组:LAMBDA函数进行遍历运算的数组,为单元格引用时可以是单列、单行或者多行多列的区域。
acc 累积器变量:类似“容器”,保存每一步计算后的中间结果,并自动传递给下一次迭代计算。
curr当前元素:在遍历数组时,当前正在被处理的单个元素值,随循环依次更新。
calculation:运算表达式:对累加器变量和当前元素进行运算的表达式,通过此表达式进行运算并返回最终结果。
函数应用示例
一、REDUCE函数与SCAN函数返回结果对比
如下图所示:求数据区域中A2:B4单元格各数据的乘积。
在D2单元格输入公式“=SCAN(,A2:B4,LAMBDA(x,y,x*y))”;在G2单元格输入公式“=REDUCE(,A2:B4,LAMBDA(x,y,x*y))”;在H2单元格输入公式“=PRODUCT(A2:B4)”,各公式的返回结果如下图所示:
从结果可以看出:SCAN函数体现了每一步的计算过程(每一步计算的结果都返回了);REDUCE和PRODUCT函数只返回了最终的计算结果。REDUCE函数想要查看每一步的计算结果,可以将公示改为“=REDUCE(,A2:B4,LAMBDA(x,y,VSTACK(x,TAKE(x,-1)*y)))”。LAMBDA函数运算体部分每次使用take函数提取累加器x中的最后一个数据,然后与当前数据y求乘积,再使用VSTACK函数垂直堆叠在累加器x下方。如下图所示:
二、连接字符串(相当于textjoin函数)
如下图所示,要将数据区域A1:B4用“、”连接成一个字符串,只需输入公式“=REDUCE(,A1:B4,LAMBDA(x,y,x&"、"&y))”,函数返回的结果与TEXTJOIN函数完全一致。
三、大写字母前加空格
如下图,在A列中存放了文本数据,现需要将大写字母前边加上一个空格。首字母前不需要添加。在B列单元格中输入公式“=TRIM(REDUCE(A6:A9,UNICHAR(ROW(65:90)),LAMBDA(x,y,SUBSTITUTE(x,y," "&y))))”。公式中参数UNICHAR(ROW(65:90))生成序列号65~90对应的字符,也就是大写字母A-Z,如下图所示。LAMBDA运算体部分用空格加大写字母替换原来的大写字母。最后用TRIM函数去掉多余的空格。利用替换功能,还可以一次性替换多个字符串,有兴趣的朋友可以试试。如下图所示,根据各门店上半年的营业额信息,统计1-6月以及各门店各月的总营业额。 | =BYROW(B14:G18,LAMBDA(a,REDUCE(,a,LAMBDA(x,y,x+y)))) |
| =REDUCE("1-6合计",OFFSET(B13:G13,SEQUENCE(5),),LAMBDA(x,y,VSTACK(x,SUM(y)))) |
| =BYCOL(B14:G18,LAMBDA(a,REDUCE(,a,LAMBDA(x,y,x+y)))) |
| =REDUCE("各店铺合计",OFFSET(A14:A18,,SEQUENCE(6)),LAMBDA(x,y,HSTACK(x,SUM(y)))) |
从I13和A20单元格的公式可以看出REDUCE函数的第二个参数也支持OFFSET函数生成的多维引用。如下图所示,将A列和B列文本数据按C列要求的重复次数进行展开。在E7单元格输入公式"=REDUCE(A7:B7,C8:C10,LAMBDA(x,y,VSTACK(x,IF(SEQUENCE(y),OFFSET(y,,-2,,2)))))"。公式中REDUCE函数的第一个参数为A7:B7,结果返回值将包含这两个列标题,将C列的数据作为遍历循环的参数,运算体中IF(SEQUENCE(y)确定重复的次数,确保重复次数在1~C列对应数据之间。如果满足条件就将y向左移动两列,返回的宽度为2,也就是A和B列的数据。每次计算的结果通过VSTACK函数垂直堆叠。结果如下图所示:如下图所示,将B列中的文本进行逆转显示,在H8单元格输入公式“=BYROW(B8:B10,LAMBDA(a,REDUCE(,MID(a,SEQUENCE(100),1),LAMBDA(x,y,y&x))))”。公式首先通过byrow函数,将B8:B10单元格按行逐个拆解,将其通过运算体LAMBDA定义为变量a,其运算表达式为REDUCE函数,采用mid函数逐个提取a中的字符,提取开始的位置为1~一个足够大的数,比如这里的100,然后通过运算体表达式y&x实现逆转显示。结果如下图所示: 近期介绍的这些Excel365新增函数都比较抽象,理解起来不是很直观,在实际应用时可能会因为一点小小的不同便产生完全不同的结果。当遇到这种情况时也不要气馁,从简单的示例开始,逐个参数改变练习,看看返回结果的不同之处,练习多了逐渐就有深刻理解了。