处理数组是 JavaScript 日常开发中最频繁的工作,而 map、filter、reduce 是最值得优先掌握的三个数组方法。它们的共同优点是不修改原数组,而是返回一个新数组或新值,代码更短也更不容易出 bug。
map:把每个元素变成另一个样子
map 对数组中每个元素执行一次函数,把所有返回值收集成一个新数组。新数组长度和原数组一致。
const nums = [1, 2, 3, 4];
const doubled = nums.map(n => n * 2);
console.log(doubled); // 输出:[2, 4, 6, 8]
const names = ["小明", "小红"];
const hello = names.map(n => "你好," + n);
console.log(hello); // 输出:["你好,小明", "你好,小红"]
对象数组也常用 map 来"挑字段"或"加字段":
const users = [
{ name: "小明", age: 17 },
{ name: "小红", age: 21 },
];
const nameList = users.map(u => u.name);
console.log(nameList); // 输出:["小明", "小红"]
filter:按条件筛选元素
filter 对每个元素执行判断函数,返回值为 true 的元素才会进入新数组,所以新数组长度小于等于原数组。
const nums = [5, 12, 8, 20, 3];
const big = nums.filter(n => n > 8);
console.log(big); // 输出:[12, 20]
const users = [
{ name: "小明", age: 17 },
{ name: "小红", age: 21 },
{ name: "小刚", age: 19 },
];
const adults = users.filter(u => u.age >= 18);
console.log(adults.length); // 输出:2(小红、小刚)
reduce:把数组聚合成一个值
reduce 稍微特殊:它不是返回数组,而是把数组"压缩"成一个值。它接收一个累积函数和一个初始值,累积函数的参数是 (累计结果, 当前元素)。
const nums = [1, 2, 3, 4];
const sum = nums.reduce((acc, n) => acc + n, 0);
console.log(sum); // 输出:10
// 初始值换成对象,还能统计出现次数
const words = ["apple", "banana", "apple"];
const count = words.reduce((acc, w) => {
acc[w] = (acc[w] || 0) + 1;
return acc;
}, {});
console.log(count); // 输出:{ apple: 2, banana: 1 }
三连招组合使用
这三个方法可以链式调用:先用 filter 筛选,再用 map 转换,最后用 reduce 汇总。可读性远高于写一大段 for 循环。
const orders = [
{ item: "键盘", price: 300, paid: true },
{ item: "鼠标", price: 120, paid: false },
{ item: "显示器", price: 900, paid: true },
];
// 只统计已支付订单的总金额
const total = orders
.filter(o => o.paid)
.map(o => o.price)
.reduce((acc, p) => acc + p, 0);
console.log(total); // 输出:1200
什么时候用哪个
记住一句口诀:形状不变用 map,挑出子集用 filter,多个变一个用 reduce。比如把价格数组换成含税价格用 map;从商品列表挑出打折商品用 filter;把购物车算成总价用 reduce。三者都不改变原数组,这在多个地方共用同一份数据时特别重要——不用担心副作用。
小结
本文介绍了 JavaScript 数组三大常用方法:map 负责一一映射生成新数组,filter 负责按条件筛选子集,reduce 负责把数组聚合成单个值;三者可以链式组合完成复杂的数据加工。建议动手把文中的例子跑一遍,再找一段自己代码里的 for 循环,试着用这三个方法重写,体会声明式写法的简洁。
评论 0
还没有评论,来抢沙发吧~ 🛋