JavaScript 中的 reduce
方法详解
#
reduce
是 JavaScript 数组中非常强大且常用的方法,用于将数组中的所有元素通过一个函数累积为单个值。
🎯 基本概念 #
reduce()
方法对数组中的每个元素按顺序执行一个提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。
📝 语法结构 #
array.reduce(callback(accumulator, currentValue[, index[, array]]), initialValue)
参数说明: #
callback
:执行数组中每个值的函数,包含四个参数:accumulator
:累积器,累积回调的返回值currentValue
:数组中正在处理的当前元素index
(可选):数组中正在处理的当前元素的索引array
(可选):调用 reduce 的数组本身
initialValue
(可选):作为第一次调用 callback 函数时的第一个参数的值
🔍 工作原理 #
想象一下 reduce
的工作过程就像是在做累加:
数组: [a, b, c, d]
reduce 过程:
步骤1: initialValue + a → 结果1
步骤2: 结果1 + b → 结果2
步骤3: 结果2 + c → 结果3
步骤4: 结果3 + d → 最终结果
💡 基本示例 #
1. 数组求和(最经典用法) #
const numbers = [1, 2, 3, 4, 5];
// 使用 reduce 求和
const sum = numbers.reduce((accumulator, currentValue) => {
return accumulator + currentValue;
}, 0);
console.log(sum); // 输出: 15
// 简写形式
const sumShort = numbers.reduce((acc, cur) => acc + cur, 0);
2. 数组求乘积 #
const numbers = [1, 2, 3, 4];
const product = numbers.reduce((acc, cur) => acc * cur, 1);
console.log(product); // 输出: 24
🚀 高级应用示例 #
1. 查找最大值 #
const numbers = [10, 5, 25, 3, 18];
const max = numbers.reduce((acc, cur) => {
return Math.max(acc, cur);
}, numbers[0]);
console.log(max); // 输出: 25
// 更简洁的写法
const maxShort = numbers.reduce((acc, cur) => Math.max(acc, cur));
2. 数组元素分组 #
const people = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 25 },
{ name: 'David', age: 30 }
];
// 按年龄分组
const groupedByAge = people.reduce((acc, person) => {
const age = person.age;
if (!acc[age]) {
acc[age] = [];
}
acc[age].push(person);
return acc;
}, {});
console.log(groupedByAge);
// 输出: {25: [{name: 'Alice', age: 25}, {name: 'Charlie', age: 25}], 30: [...]}
3. 数组去重 #
const numbers = [1, 2, 2, 3, 4, 4, 5, 5, 5];
const uniqueNumbers = numbers.reduce((acc, cur) => {
if (!acc.includes(cur)) {
acc.push(cur);
}
return acc;
}, []);
console.log(uniqueNumbers); // 输出: [1, 2, 3, 4, 5]
// 使用 Set 的更现代方法(ES6)
const uniqueWithSet = [...new Set(numbers)];
4. 计算元素出现次数 #
const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const fruitCount = fruits.reduce((acc, fruit) => {
acc[fruit] = (acc[fruit] || 0) + 1;
return acc;
}, {});
console.log(fruitCount);
// 输出: {apple: 3, banana: 2, orange: 1}
5. 扁平化二维数组 #
const nestedArray = [[1, 2], [3, 4], [5, 6]];
const flatArray = nestedArray.reduce((acc, cur) => {
return acc.concat(cur);
}, []);
console.log(flatArray); // 输出: [1, 2, 3, 4, 5, 6]
// 使用 flat() 的现代方法(ES2019)
const flatWithMethod = nestedArray.flat();
6. 管道函数组合 #
// 组合多个函数
const double = x => x * 2;
const increment = x => x + 1;
const square = x => x * x;
// 创建函数管道
const pipe = (...functions) => input => {
return functions.reduce((acc, func) => {
return func(acc);
}, input);
};
const transform = pipe(double, increment, square);
console.log(transform(5)); // 输出: 121 ( (5*2)+1 = 11, 11*11 = 121 )
⚠️ 注意事项 #
1. 始终提供初始值 #
const numbers = [1, 2, 3];
// 不提供初始值 - 使用数组第一个元素作为初始值
const sum1 = numbers.reduce((acc, cur) => acc + cur);
console.log(sum1); // 输出: 6
// 提供初始值 - 更安全
const sum2 = numbers.reduce((acc, cur) => acc + cur, 0);
console.log(sum2); // 输出: 6
2. 空数组处理 #
const emptyArray = [];
// 不提供初始值会报错
try {
emptyArray.reduce((acc, cur) => acc + cur);
} catch (e) {
console.log('错误:', e.message); // TypeError: Reduce of empty array with no initial value
}
// 提供初始值则安全
const result = emptyArray.reduce((acc, cur) => acc + cur, 0);
console.log(result); // 输出: 0
📊 reduce 与其他数组方法对比 #
方法 | 用途 | 返回值 |
---|---|---|
reduce() | 将数组累积为单个值 | 任意类型的单个值 |
map() | 转换每个元素 | 新数组 |
filter() | 筛选元素 | 新数组 |
forEach() | 遍历执行操作 | undefined |
💡 总结 #
reduce
是用于将数组元素累积为单个值的强大方法- 它接收一个 reducer 函数 和一个可选的 初始值
- reducer 函数接收四个参数:累积值、当前元素、当前索引、原数组
- 始终提供初始值 可以避免空数组错误并使代码更清晰
- 除了数学运算,还可以用于分组、计数、扁平化等复杂操作
- 在函数式编程中,reduce 是构建复杂操作的基础工具
reduce
是 JavaScript 函数式编程的核心方法之一,掌握它可以让你更优雅地处理各种数组操作任务。