分享

MAP函数用过没?

 存入仓库 2022-08-02 发布于河北



每天一篇Excel技术图文
微信公众号:Excel星球

NO.1641-MAP函数
作者:看见星光
 B站/微博:Excel星球 

HI,大家好,我是星光。

上一期给大家聊了BYROW函数,末尾留了一个多关键词查询的案例,当时我们说图片,当计算对象是单列多行数据时,用MAP函数比BYROW函数更适合。这期就给大家聊一下MAP函数。

图片

👆点击图片阅读BYROW函数教程

语法概要

1)基础语法

以下是MAP的语法格式:

=MAP( 数组,  数组或LAMBDA自定义表达式1,  数组或LAMBDA自定义表达式2,  ……  数组或LAMBDA自定义表达式n)

第1参数是数组,第2等参数是数组或LAMBDA表达式。系统按照从上到下、从左到右的顺序,遍历数组中的每个元素,执行LAMBDA表达式,最后返回和源数组尺寸相同的结果数组。

打个响指,看语法看不出花来,我们还是举个简单的例子。

图片

如上图所示,是一张成绩表。现在,需要对每个人的语文成绩加10分。为什么加10分呢?听说是庆祝祖国即将统一了。

MAP函数的解法如下:

=MAP(D2:D9,LAMBDA(_m,_m+10)) 

MAP函数第1参数是D2:D9,系统从上到下依次遍历数组中的每个元素,也就是D2/D3/D4/...D9,每个元素执行LAMBDA表达式。

LAMBDA表达式第1参数属于自定义名称(_m),指向第1个数组中每个被遍历的元素,第2参数是计算方式(_m+10),在原值的基础上加10。

公式返回结果如下图所示。

图片

……

2)遍历顺序

当MAP函数的数组参数是多行多列时,会按照从上到下、从左到右的顺序遍历。

还是举个简单例子。以同样的数据为例,不但语文要加10分,数学也要加10分。嗯,快乐总是相似的图片

MAP函数解法如下:

=MAP(D2:E9,LAMBDA(_m,_m+10))

MAP函数第1参数是D2:E9,8行2列。系统按照从上到下、从左到右的顺序遍历该数组,也就是D2/E2/D3/E3……依次执行LAMBDA表达式,每个元素+10,返回一个和源数组尺寸相等的结果数组,8行2列,如下图所示:

图片

……

3)多数组参数

MAP函数支持多个数组作为参数。

例如,需要计算每个人的成绩总分,MAP函数解法如下:

=MAP(D2:D9,E2:E9,LAMBDA(_a,_b,_a+_b)) 

MAP函数第1参数是源数组1:D2:D9,第2参数是源数组2:E2:E9;第3参数是LAMBDA表达式。

LAMBDA第1个参数是自定义名称(_a)指向源数组1,第2个自定义名称(_b)指向源数组2。系统按顺序遍历源数组中的每个元素,_a依次指向D2/D3/..D9。_b依次指向E2/E3/..D9,两者依次相加即为每个人的成绩总分。

从这个计算规则中,你就可以发现,当数组有多个时,它们的尺寸大小必须一致,不然按照数组运算规则,会导致配对元素缺失,进而产生错误值。

图片

……

4)保留引用特性

和BYROW函数一样,但源数组为引用时,MAP也会保留引用的特性。摊手,如果你忘记了什么是引用,最好是重新看下新手教程里的什么是Excel数据类型章节。

举个简单的例子。

图片

如上图所示,需要在G列用动态数组的形式,统计每个班级累加出现的次数。

MAP函数参考解法如下:

=MAP(A2:A9,LAMBDA(_m,COUNTIF(A1:_m,_m)))

MAP第1参数是引用性质的数组A2:A9,系统遍历该数组每个元素,执行LAMBDA表达式。_m指向源数组被遍历的元素,比如A2,COUNTIF函数第1参数是A1:_m,表示统计范围,比如A1:A2,在这个范围中统计A2出现的次数。下一个遍历元素为A3,_m指向A3,COUNTIF在A1:A3中统计A3出现的次数……其余以此类推。

实战案例

坦白但不露胸说,以上案例,都是简单的,只是为了表达MAP函数的运算特点,很明显,它们并非MAP不可。MAP函数最常用的场景还是将计算结果作为内存数组的形式,传递给其它函数。换句话说,它只是一个计算过程,而非最终结果。

再举两个例子,这两例子虽然实际工作中不常见,但计算过程比较典型。更多实用的案例,可以参考我们的100道练习题系列。 

1)字符串筛选、拆分与合并

图片

如上图所示,A列的数据混合了班级、姓名和性别等数据,需要从中获取男性的名单,并合并成一个字符串。

参考解法如下:

=TEXTJOIN('-',1,  MAP(A2:A9,    LAMBDA(_m,      IF(RIGHT(_m)='男',        INDEX(TEXTSPLIT(_m,'-'),2),       '')     )   ) ) 

MAP函数遍历A2:A9区域,如果最右边的字符不为男,则返回假空,否则使用TEXTSPLIT函数按分隔符'-'将其拆分,再使用INDEX函数取出姓名。

图片

2)字符串拆分与内部计数

如下图所示,A2:A8单元格内存在多个人名,不同人名之间使用分隔符'-'相连。

图片

现在需要统计每个单元格内部每个人名累加出现的次数,模拟结果如下:

图片

MAP函数参考解法如下,B2单元格输入以下公式向下复制填充。

公式看不全可以左右拖动..

=LET( _a,TEXTSPLIT(A2,'-'), _b,SEQUENCE(1,COUNTA(_a)), TEXTJOIN('-',1, MAP(_a,_b, LAMBDA(_x,_y, _x&COUNT(0/((_a=_x)*(_b<=_y)))&'次')    )  ))

第2行代码使用TEXTSPLIT函数将A2单元格按分隔符'-'拆分,并赋值变量_a。

{'看见星光','二肥','超人','看见星光','看见星光'} 

第3行代码统计数组_a元素的个数,生成一个递增水平序列,赋值变量_b。

{1,2,3,4,5}

这个时候,我们就可以假设,得到了一个虚拟的二维数组,如下图所示:

图片

然后,我们使用MAP函数,遍历这个虚拟数组。

MAP函数第1参数为_a,为每个人名元素,第2参数_b,为水平序列。在LAMBDA表达式中,使用COUNT函数统计所有人名等于当前人名,并且所有序列小于等于当前序列的个数,也就是每个人名累加出现的次数。

最后使用TEXTJOIN函数将结果合并即可。

……

当我们使用了显性遍历的函数,诸如MAP/BYROW/SCAN/REDUCE等时,最好使用动态数组的形式,一次性返回全部结果,这可以避免反复调取单元格对象到内存中,以至于严重拖累计算速度——这也是我们一直说的,如果WPS不支持动态数组,则引入Excel新函数体系无意义,因为它压根带不起这批函数的计算速度。

以上述问题为例,如果使用一条函数公式,返回B列全部计算结果,可以在外部嵌套一个REDUCE函数。在B1单元格输入以下公式即可:

=REDUCE('数据',A2:A8,LAMBDA(_p,_v,  LET(    _a,TEXTSPLIT(_v,'-'),    _b,SEQUENCE(1,COUNTA(_a)),    _c,TEXTJOIN('-',,      MAP(_a,_b,LAMBDA(_x,_y,        _x&COUNT(0/((_a=_x)*(_b<=_y)))&'次')      )),    VSTACK(_p,_c)  )))
图片

……

摊手,今天给大家分享的内容就这样吧,有啥问题照例可以在VIP会员群中提问交流↓↓ 挥挥手,关于REDUCE函数的讲解,咱们以后的推文中再见。

需要系统学习Excel,却找不到优质教程?学习Excel的过程中遇到疑难问题,却找不到人及时作出解答?加入我的付费社群,与4500+学员一起,同微软最有价值专家(MVP)全面精进表格之道👇

👀

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多