JavaScript 的数组高阶函数是函数式编程的核心工具,它们接收函数作为参数,使代码更简洁、可读且易于维护。其中最常用的三个是 filter、map 和 reduce。
const newArray = array.filter(callback(element, index, array));
true 时保留元素,false时过滤掉const numbers = [1, 2, 3, 4, 5, 6];
// 过滤出偶数
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4, 6]
// 过滤出大于3的数
const greaterThanThree = numbers.filter(num => num > 3);
console.log(greaterThanThree); // [4, 5, 6]
const users = [
{ id: 1, name: 'Alice', age: 25, active: true },
{ id: 2, name: 'Bob', age: 30, active: false },
{ id: 3, name: 'Charlie', age: 35, active: true },
{ id: 4, name: 'David', age: 20, active: false }
];
// 过滤活跃用户
const activeUsers = users.filter(user => user.active);
console.log(activeUsers); // Alice 和 Charlie
// 过滤年龄大于25的用户
const olderUsers = users.filter(user => user.age > 25);
console.log(olderUsers); // Bob 和 Charlie
const newArray = array.map(callback(element, index, array));
const numbers = [1, 2, 3, 4];
// 将每个数字加倍
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8]
// 将数字转换为字符串
const strings = numbers.map(num => `数字: ${num}`);
console.log(strings); // ["数字: 1", "数字: 2", "数字: 3", "数字: 4"]
const products = [
{ id: 1, name: 'Laptop', price: 999, tax: 0.1 },
{ id: 2, name: 'Mouse', price: 25, tax: 0.08 },
{ id: 3, name: 'Keyboard', price: 75, tax: 0.08 }
];
// 提取产品名称数组
const productNames = products.map(product => product.name);
console.log(productNames); // ["Laptop", "Mouse", "Keyboard"]
// 计算含税价格
const pricesWithTax = products.map(product => ({
name: product.name,
totalPrice: product.price * (1 + product.tax)
}));
console.log(pricesWithTax);
// [
// { name: 'Laptop', totalPrice: 1098.9 },
// { name: 'Mouse', totalPrice: 27 },
// { name: 'Keyboard', totalPrice: 81 }
// ]
const result = array.reduce(callback(accumulator, currentValue, index, array), initialValue);
const numbers = [1, 2, 3, 4, 5];
// 求和
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 15
// 求乘积
const product = numbers.reduce((acc, curr) => acc * curr, 1);
console.log(product); // 120
// 找出最大值
const max = numbers.reduce((acc, curr) => Math.max(acc, curr), -Infinity);
console.log(max); // 5
const orders = [
{ id: 1, product: 'Apple', quantity: 2, price: 1.5 },
{ id: 2, product: 'Banana', quantity: 3, price: 0.5 },
{ id: 3, product: 'Orange', quantity: 1, price: 2.0 }
];
// 计算总销售额
const totalSales = orders.reduce((total, order) => {
return total + (order.quantity * order.price);
}, 0);
console.log(totalSales); // (2*1.5 + 3*0.5 + 1*2.0) = 6.5
// 按产品分组统计
const productSummary = orders.reduce((summary, order) => {
if (!summary[order.product]) {
summary[order.product] = 0;
}
summary[order.product] += order.quantity;
return summary;
}, {});
console.log(productSummary); // { Apple: 2, Banana: 3, Orange: 1 }
const employees = [
{ name: 'Alice', department: 'IT', salary: 60000, years: 3 },
{ name: 'Bob', department: 'HR', salary: 45000, years: 5 },
{ name: 'Charlie', department: 'IT', salary: 75000, years: 7 },
{ name: 'David', department: 'Marketing', salary: 50000, years: 2 },
{ name: 'Eve', department: 'IT', salary: 80000, years: 10 }
];
// 计算IT部门平均工资
const itAverageSalary = employees
.filter(emp => emp.department === 'IT') // 1. 过滤IT部门
.map(emp => emp.salary) // 2. 提取工资
.reduce((sum, salary, index, array) => { // 3. 计算平均值
sum += salary;
if (index === array.length - 1) {
return sum / array.length;
}
return sum;
}, 0);
console.log(itAverageSalary); // (60000 + 75000 + 80000) / 3 = 71666.67
const data = [
{ id: 1, value: 10, category: 'A' },
{ id: 2, value: 25, category: 'B' },
{ id: 3, value: 15, category: 'A' },
{ id: 4, value: 30, category: 'C' },
{ id: 5, value: 20, category: 'B' }
];
// 按类别分组并计算每类的总和
const result = data
.filter(item => item.value > 15) // 过滤值大于15的项
.reduce((groups, item) => {
if (!groups[item.category]) {
groups[item.category] = [];
}
groups[item.category].push(item);
return groups;
}, {});
// 进一步处理分组结果
const finalResult = Object.keys(result).map(category => ({
category,
count: result[category].length,
total: result[category].reduce((sum, item) => sum + item.value, 0)
}));
console.log(finalResult);
// [
// { category: 'B', count: 2, total: 45 },
// { category: 'C', count: 1, total: 30 }
// ]
// 链式调用(可读性好)
const result1 = array
.filter(x => x > 10)
.map(x => x * 2)
.reduce((sum, x) => sum + x, 0);
// 单一循环(性能更好)
const result2 = array.reduce((sum, x) => {
if (x > 10) {
return sum + (x * 2);
}
return sum;
}, 0);
// 推荐:先过滤再映射
const validItems = largeArray
.filter(item => item.isValid) // 先过滤掉无效项
.map(item => item.value); // 再处理有效项
// 不推荐:先映射再过滤
const notRecommended = largeArray
.map(item => item.value) // 可能计算了无效项
.filter(value => value !== null);
| 特性 | filter | map | reduce |
|---|---|---|---|
| 返回值 | 新数组 | 新数组 | 单个值 |
| 数组长度 | 可能减少 | 保持不变 | N/A |
| 主要用途 | 过滤/选择 | 转换/映射 | 聚合/累积 |
| 是否改变原数组 | 否 | 否 | 否 |
| 回调函数返回值 | Boolean | 任意类型 | 累积值 |
这三个函数组合使用可以解决大多数数组处理问题,使代码更加声明式、简洁且易于维护。掌握它们能显著提升 JavaScript 编程能力。