从头使用.map() .filter() 和.reduce()这三个函数,你会有意想不到的收获!


全文共2556字,预计学习时长8分钟

来源:Pexels

世间纷乱复杂,我们在不断给自身做“加法”的同时,也要学会对周围的事物做“减法”,将复杂的东西简化,为我所用,并发挥超出原本程度的增幅效果,这才是真正的“高手”。

 

在“码农圈”,学习如何使用.map()、.filter()和.reduce()函数,我们读到、看到和听到的一切都很复杂,无法理解这些概念,因为它们是独立的学习单元。

 

听说这些是意味着上升至启蒙状态的入门知识。真希望自己听到的是实话:早点明白这三种方法其实都是识别和实现过程,循环遍历迭代的原因通常属于三个功能类别之一。

 

回顾之前编写的代码,笔者发现95%的情况下,在对字符串或数组进行循环时,自己都会执行以下操作之一:将语句序列映射(map)到每个值,过滤(filter)满足特定条件的值,或者将数据集减少(reduce)到单个聚合值。

 

这是取得进步的关键时刻,Map、filter和reduce只需要执行其中的一个任务即可!

来源:Pexels

为了练习,笔者使用这些方法对旧代码进行重构,这真是帮了大忙!

 

言归正传,继续讲解学习内容。本文将解释每种方法,然后将常用 for循环的实现转换为这三个各自的方法。

 

Map

 

.map()方法使用在:1.用可迭代的每个值执行一组语句;2.返回(可能)修改值。                                     

 

用一个简单的示例来计算一系列价格的营业税:

 

const prices = [19.99, 4.95, 25, 3.50];
let new_prices = [];for(let i=0; i < prices.length; i++) {
   new_prices.push(prices[i] * 1.06);
}

用.map()方法可以得出同样的结果:

 

const prices= [19.99, 4.95, 25, 3.50];let new_prices = prices.map(price => price *1.06);

上面的语法简明扼要,所以简单过一遍即可。

 

.map()函数采用回调,可以将其视为一个函数,这便是括号之间的含义。

 

 price变量用于标识每个值的名称,由于只有一个变量输入,所以可以省略参数周围的常用括号。

 

箭头=>后的语句是回调的主体。由于主体只有一条语句,可以省略大括号和return关键字。

 

以防部分学习者无法理解,具体代码如下,供详细参考:

 

const prices= [19.99, 4.95, 25, 3.50];let new_prices = prices.map((price) => {
   return price * 1.06
});

Filter

 

当要从可迭代对象中提取值的子集时,.filter() 方法就派上了用场。使用.filter()时,请记住是在筛选值,而不是筛除值。这就意味着,迭代器中评估为true的每个项目,都将包含在过滤器中。

 

举一个只保留奇数的例子:使用模运算符来计算除以2的余数。当余数等于1,就得知这个数是奇数。

 

const numbers = [1,2,3,4,5,6,7,8];
let odds = [];for(let i=0; i < numbers.length; i++) {
   if(numbers[i] % 2 == 1) {
      odds.push(numbers[i]);
   }


}与.map()类似,.filter()可以接受单个回调,以将可迭代对象中的每个值传递到该回调。

 

constnumbers = [1,2,3,4,5,6,7,8];let odds = numbers.filter(num => num % 2);

此回调也适用类似的规则。由于只有一个输入,且函数的主体是单个表达式,因此可以省略参数列表括号、定义主体的大括号和return关键字。

 

Reduce

 

最后,来看看.reduce()。诚然,它是三种方法中最让人困惑的方法。从术语名称来看,Reduce方法是指将多个值缩减为一个。然而,笔者发现,与“减少”相比,把它想成是“积累”更容易操作。

 

该方法通过定义起点来运行。当该方法迭代每个值时,该起点将被修改并向下传递。

 

这是将一系列数字相加的经典案例。假设正在计算某人最喜欢的慈善机构的捐款总额:

 

constdonations = [5, 20, 100, 80, 75];
let total = 0;for(let i=0; i < donations.length; i++) {
   total += donations[i];
}

与.map()和.filter()不同,.reduce()方法的回调需要两个参数:累加器和当前值。累加器将是第一个参数,是“向下传递”值。

 

constdonations = [5, 20, 100, 80, 75];let total = donations.reduce((total,donation)=> {
   return total + donation;
});

还可以将第二个参数传递给 .reduce()函数本身,作为累加器的起始值。假设加上昨天总共450美元的捐款。

 

constdonations = [5, 20, 100, 80, 75];let total = donations.reduce((total,donation)=> {
   return total + donation;
}, 450);

然后就能得到运行结果,这些方法并不可怕,它们能让代码更具可读性!这样就可以编写更精简的代码啦,更重要的是,这实际上是在描述循环意图!

来源:Pexels

在三个月后回顾代码时,我们的阅读将变得更轻松。不必阅读for循环中的语句,只需理解它的高级意图,就可以看到map/filter/reduce方法,并能开始对该块试图实现的目标有所想法了。

 

就像“哥伦布发现新大陆”一般,面对如此大的进步,我兴奋不已,你呢?


推荐阅读专题

留言 点赞 发个朋友圈

我们一起分享AI学习与发展的干货

编译组:齐鑫濛、吴亚芳

相关链接:

https://medium.com/better-programming/how-to-start-using-map-filter-and-reduce-e01edba0d81

如需转载,请后台留言,遵守转载规范

推荐文章阅读

ACL2018论文集50篇解读

EMNLP2017论文集28篇论文解读

2018年AI三大顶会中国学术成果全链接

ACL2017 论文集:34篇解读干货全在这里

10篇AAAI2017经典论文回顾

长按识别二维码可添加关注

读芯君爱你

发布了691 篇原创文章 · 获赞 2327 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/duxinshuxiaobian/article/details/103790413