Array.reduce
目录
46. reduce
方法及其常见的使用场景
46.1. reduce 方法基本语法
array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
callback
: 执行数组中每个值的函数,包含四个参数:accumulator
: 累加器,累加回调的返回值currentValue
: 数组中正在处理的元素index
(可选): 数组中正在处理的当前元素的索引array
(可选): 调用reduce()
的数组
initialValue
(可选): 作为第一次调用callback
函数时的第一个参数的值- ==注意:如果不传时,调用空数组会报错==
accumulator
是返回值,函数需要显式返回该值才行
46.2. 使用场景
46.2.1. 数组求和
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 输出: 15
46.2.2. 数组中最大值
const numbers = [5, 2, 8, 1, 9];
const max = numbers.reduce((acc, cur) => Math.max(acc, cur));
console.log(max); // 输出: 9
有点麻烦,直接
Math.max(...numbers)
即可
46.2.3. 数组扁平化
const nestedArray = [1, 2], [3, 4], [5, 6](/post/3ZX7oZRr.html#1,-2],-[3,-4],-[5,-6);
const flatArray = nestedArray.reduce((acc, cur) => acc.concat(cur), []);
console.log(flatArray); // 输出: [1, 2, 3, 4, 5, 6]
46.2.4. 计算数组中元素出现的次数
const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const count = fruits.reduce((acc, cur) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc;
}, {});
console.log(count); // 输出: { apple: 3, banana: 2, orange: 1 }
46.2.5. 按条件分组
const people = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 25 },
{ name: 'David', age: 30 }
];
const groupedByAge = people.reduce((acc, person) => {
(acc[person.age] = acc[person.age] || []).push(person);
return acc;
}, {});
console.log(groupedByAge);
// 输出: {
// 25: [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }],
// 30: [{ name: 'Bob', age: 30 }, { name: 'David', age: 30 }]
// }
46.2.6. 串联 Promise
这个也能够保证串行,也可以使用 async / await 等方法
const asyncTasks = [
() => new Promise(resolve => setTimeout(() => resolve('Task 1'), 1000)),
() => new Promise(resolve => setTimeout(() => resolve('Task 2'), 500)),
() => new Promise(resolve => setTimeout(() => resolve('Task 3'), 800))
];
asyncTasks.reduce((acc, task) =>
acc.then(results =>
task().then(result => [...results, result])
),
Promise.resolve([])
).then(console.log);
// 输出: ['Task 1', 'Task 2', 'Task 3']
46.2.7. 实现 pipe 或 compose 函数
管道 pipe,本质还是函数式编程
const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);
const addOne = (x) => x + 1;
const double = (x) => x * 2;
const square = (x) => x * x;
const compute = pipe(addOne, double, square);
console.log(compute(3)); // 输出: 64 ((3 + 1) * 2)^2
说实话,我很讨厌这种写法:
(...fns) => (x) => fns.reduce((v, f) => f(v), x);
炫技,代码最终还是写给人看的,换个行就会好多了,谢谢!
46.2.8. 提取对象中的特定字段
const users = [
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 30 },
{ id: 3, name: 'Charlie', age: 35 }
];
const names = users.reduce((acc, user) => [...acc, user.name], []);
console.log(names); // 输出: ['Alice', 'Bob', 'Charlie']