|

楼主 |
发表于 2022-6-1 00:15
|
显示全部楼层
本帖最后由 shaowu459 于 2022-6-1 08:37 编辑
第15个函数:MAP函数。
用官方文件中的说法,MAP函数可以对参数数组中的每个元素映射到一个新值,生成一个新的数组。该函数语法如下:
MAP(数组1,数组2,数组3……,lambda(x,y,z……),lambda之前的参数可以是一个也可以是多个,如果映射多个数组的话,数组大小应该一样,否则会返回错误值或返回值中包含错误。其实简单理解,可以认为MAP函数循环对数组中的每个值进行在特定的运算,返回一个单值,每个返回的单值形成一个新的数组。下面用示例来说明MAP函数基本用法。LAMBDA里面的x、y、z等分别对应数组1、数组2、数组3中的每个元素。
下面的公式使用MAP函数对A1:C3这个数组中的每个元素进行平方运算,x就代表A1:C3中的每个元素,运算完毕后的值重新组成3行3列的数组,可以里成运算后的平方数替代了原位置的数据。以A1的1为例,经过平方运算后返回值为1,生成新数组最左上角的元素1;以A2的2为例,经过平方运算后返回值为4,生成新数组第1行第2列的元素,后面以此类推。
- =MAP(A1:C3,LAMBDA(x,x^2))
复制代码
MAP函数对每个数组元素映射完毕后生成的值只能是单值,不能是数组,否则会出现错误。例如,希望循环A5:A7每个单元格,并且取每个单元格及右侧两个单元格形成一个3行数组,会返回错误:
如果用其他函数将数组聚合一下返回单值,是可以的。例如用TEXTJOIN函数将每行的3个元素合并在一起:
通过上面的一个例子可以看出,MAP函数引用的数组如果是单元格区域,那么在循环的时候,每个元素还是一个单元格区域,也就是可以用于SUMIF函数、OFFSET函数等函数的ref或range,ROW(循环的元素)也可以返回单元格所在的行。这个特性也是经常被使用的一个特性。下面举例来说明:
以下公式能筛选出A列对应的每个名称B列最小值所在的行(MAP函数和FILTER函数也是好搭档,经常合作):
- =FILTER(A14:B25,MAP(B14:B25,LAMBDA(x,MIN(FILTER(B14:B25,A14:A25=OFFSET(x,,-1)))=x)))
复制代码
MAP函数第一参数数组是B14:B25单元格区域,因此MAP函数将循环对区域中的每个元素进行运算和判断。以B19单元格为例,当循环到B19单元格时:
MAP函数映射运算完毕后,返回TRUE和FALSE的数组,TRUE即B列数值是A列名称对应值中的最小值。最后用FILTER函数筛选出结果为TRUE的即可。
MAP函数映射的数组可以是多个,例如要筛选出“名称”=A并且数值>5的数据,可以用以下公式:
- =FILTER(A29:B39,MAP(A29:A39,B29:B39,LAMBDA(x,y,AND(x="A",y>5))))
复制代码
上面的公式中x代表A29:A39的每个元素,y代表B29:B39的每个元素。以第一行为例,循环的值为A29和B29,AND(x="A",y>5)也即AND(A29="A",B29>5),结果返回TRUE,后面以此类推。映射完成和返回一个TRUE和FALSE的数组,最后用FILTER函数筛选TRUE对应行即可。
以下公式可以求A41:E44每个单元格及其右侧两个单元格的合计值:
- =MAP(A41:E44,LAMBDA(x,SUM(OFFSET(x,,,,3))))
复制代码
循环的第一个元素是A41单元格,LAMBDA里的x代表A41,OFFSET(x,,,,3)也即OFFSET(A41,,,,3)=A41:C41单元格区域,然后用SUM函数求和返回一个单值48。后面的值以此类推。
以下公式实现的功能是将左侧表格中每行的最大值替换成max,最小值替换成min,其余所有值都显示mid。
- =VSTACK(A53:D53,MAP(A54:D56,LAMBDA(x,LET(t,INDEX(A54:D56,ROW(x)-53,),IFS(x=MIN(t),"min",x=MAX(t),"max",1,"mid")))))
复制代码
以B54单元为例,当循环到B54单元格时,ROW(B54)-53返回1,INDEX(A54:D56,ROW(x)-53,)返回A54:D54的数组,用LET函数定义为t方便后续调用。IFS(x=MIN(t),"min",x=MAX(t),"max",1,"mid")这部分分别判断B54单元格的值是否等于t数组中的最小值或最大值,如果是则分别返回max或min,如果都不是则返回mid。
下面的公式先用UNIQUE函数提取出A60:A70单元格区域的不重复值,然后MAP函数针对每个不重复值去用SUMIF函数求对应数值合计,最后用HSTACK函数将不重复值和映射生成的数组合并在一起。
- =LET(s,UNIQUE(A60:A70),HSTACK(s,MAP(UNIQUE(A60:A70),LAMBDA(x,SUMIF(A60:A70,x,B60:B70)))))
复制代码
下图是根据论坛一个实例改编,要求返回每个客户最近3次(从下往上数,包含当前行)的购物金额合计。
- =MAP(B75:B102,LAMBDA(x,SUM(TAKE(FILTER(C75:x,B75:x=x),-3))))
复制代码
简单归纳一下,MAP函数就是对参数数组中的每个元素进行循环操作,MAP函数参数中的每个值,还可以用于其他函数,例如VLOOKUP等,通过查询返回值重新组成数组。如果MAP函数引用参数数组是单元格区域,在LAMBDA函数运算时每个元素x还带着单元格属性,可以用ROW函数返回行号、COLUMN函数返回列号、可用于OFFSET函数偏移引用等。
|
评分
-
2
查看全部评分
-
|