JavaScript 的 reduce() 方法詳解
reduce() 是 JavaScript 數(shù)組方法中功能最強(qiáng)大的方法之一,它可以將數(shù)組元素通過指定的函數(shù)累積為單個(gè)值。
基本語(yǔ)法
array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
-
callback:執(zhí)行數(shù)組中每個(gè)元素的函數(shù),包含以下參數(shù):
- accumulator:累積器,累積回調(diào)的返回值
- currentValue:數(shù)組中正在處理的當(dāng)前元素
- index(可選):當(dāng)前元素的索引
- array(可選):調(diào)用 reduce 的數(shù)組
- initialValue(可選):作為第一次調(diào)用 callback 時(shí)的第一個(gè)參數(shù)的值
基本用法示例
1. 數(shù)組求和
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 15
2. 數(shù)組求積
const product = numbers.reduce((acc, curr) => acc * curr, 1);
console.log(product); // 120
高級(jí)用法
3. 扁平化二維數(shù)組
const flattened = [[0, 1], [2, 3], [4, 5]].reduce(
(acc, curr) => acc.concat(curr),
[]
);
console.log(flattened); // [0, 1, 2, 3, 4, 5]
4. 計(jì)算元素出現(xiàn)次數(shù)
const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const count = fruits.reduce((acc, fruit) => {
acc[fruit] = (acc[fruit] || 0) + 1;
return acc;
}, {});
console.log(count); // { apple: 3, banana: 2, orange: 1 }
5. 按屬性對(duì)對(duì)象數(shù)組分組
const people = [
{ name: 'Alice', age: 21 },
{ name: 'Bob', age: 20 },
{ name: 'Charlie', age: 21 }
];
const groupedByAge = people.reduce((acc, person) => {
const age = person.age;
if (!acc[age]) {
acc[age] = [];
}
acc[age].push(person);
return acc;
}, {});
console.log(groupedByAge);
// {
// 20: [{ name: 'Bob', age: 20 }],
// 21: [
// { name: 'Alice', age: 21 },
// { name: 'Charlie', age: 21 }
// ]
// }
6. 數(shù)組去重
const numbersWithDuplicates = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = numbersWithDuplicates.reduce((acc, curr) => {
if (!acc.includes(curr)) {
acc.push(curr);
}
return acc;
}, []);
console.log(uniqueNumbers); // [1, 2, 3, 4, 5]
注意事項(xiàng)
-
初始值的重要性:
- 如果沒有提供 initialValue,reduce 會(huì)從索引 1 開始執(zhí)行 callback 方法,跳過第一個(gè)索引
- 如果數(shù)組為空且沒有提供 initialValue,會(huì)拋出 TypeError
[].reduce((acc, curr) => acc + curr); // TypeError -
空數(shù)組處理:
[].reduce((acc, curr) => acc + curr, 0); // 0 (安全) -
reduceRight:
- 類似 reduce,但是從數(shù)組的末尾向前執(zhí)行
const flattenedRight = [[0, 1], [2, 3], [4, 5]].reduceRight( (acc, curr) => acc.concat(curr), [] ); console.log(flattenedRight); // [4, 5, 2, 3, 0, 1]
實(shí)際應(yīng)用場(chǎng)景
7. 函數(shù)組合
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);
const add5 = x => x + 5;
const multiply2 = x => x * 2;
const subtract3 = x => x - 3;
const transform = compose(add5, multiply2, subtract3);
console.log(transform(10)); // ((10 - 3) * 2) + 5 = 19
8. 管道操作
const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);
const transformPipe = pipe(subtract3, multiply2, add5);
console.log(transformPipe(10)); // ((10 - 3) * 2) + 5 = 19
9. 對(duì)象屬性轉(zhuǎn)換
const obj = {
user_name: 'john_doe',
user_age: 30,
product_id: 123
};
const camelCaseKeys = Object.entries(obj).reduce((acc, [key, value]) => {
const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
acc[camelKey] = value;
return acc;
}, {});
console.log(camelCaseKeys);
// { userName: 'john_doe', userAge: 30, productId: 123 }
reduce() 方法非常靈活,幾乎可以實(shí)現(xiàn)任何基于數(shù)組的復(fù)雜轉(zhuǎn)換邏輯。掌握好 reduce 可以大大提升你的 JavaScript 編程能力。