乐于分享
好东西不私藏

159、Excel 365新增函数介绍之八---REDUCE函数

159、Excel 365新增函数介绍之八---REDUCE函数
      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月以及各门店各月的总营业额。
对应单元格输入下表公式:
H14单元格各公式:
=BYROW(B14:G18,LAMBDA(a,REDUCE(,a,LAMBDA(x,y,x+y))))
I13单元格各公式:
=REDUCE("1-6合计",OFFSET(B13:G13,SEQUENCE(5),),LAMBDA(x,y,VSTACK(x,SUM(y))))
B19单元格各公式:
=BYCOL(B14:G18,LAMBDA(a,REDUCE(,a,LAMBDA(x,y,x+y))))
A20单元格各公式:
=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函数垂直堆叠。结果如下图所示:
六、逆转字符串

106、excel函数与power query应用对比章节中介绍了逆转字符串的相关方法。在这里用REDUCE函数来逆转字符串。

如下图所示,将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新增函数都比较抽象,理解起来不是很直观,在实际应用时可能会因为一点小小的不同便产生完全不同的结果。当遇到这种情况时也不要气馁,从简单的示例开始,逐个参数改变练习,看看返回结果的不同之处,练习多了逐渐就有深刻理解了。