目录
在 JavaScript 中,reduce 是一种功能强大的数组方法,它可以逐个处理数组中的每个元素,并将其合并为一个值。它可用于各种情况,从计算总和到转换数据,因此非常有用。
基本语法
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
具体参数说明:
- function(total, currentValue, currentIndex, arr) - 必填。为每个数组元素执行的函数。
- total - 必填。初始值或计算后的返回值。
- currentValue - 必填。当前元素。
- currentIndex - 可选。当前元素的索引。
- arr - 可选。当前元素所属的数组对象。
- initialValue - 可选。传递给函数的初始值。
过程:
- 使用 total 作为累积结果的初始值。如果没有设置 total,则使用数组的第一个元素作为初始值。
- 开始迭代,用累加器处理 currentValue,将 currentValue 的映射结果累加到总数上,结束循环并返回总数。
- 进入下一个循环,重复上述操作,直到数组的最后一个元素。
- 结束迭代并返回最终总数。
使用示例
计算数组之和
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((total, currentValue) => total + currentValue, 0);
console.log(sum); // 15
转换数组元素
const words = ["Hello", "world", "this", "is", "reduce"];
const concatenated = words.reduce((total, currentValue) => total + " " + currentValue);
console.log(concatenated); // "Hello world this is reduce"
求最大值
const values = [10, 5, 8, 20, 3];
const max = values.reduce((total, currentValue) => Math.max(total, currentValue), -Infinity);
console.log(max); // 20
扁平化阵列
function Flat(arr = []) {
return arr.reduce((total, currentValue) => total.concat(Array.isArray(currentValue) ? Flat(currentValue) : currentValue), [])
}
const arr = [0, 1, [2, 3], [4, 5, [6, 7]], [8, [9, 10, [11, 12]]]];
Flat(arr); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
分割阵列
function Chunk(arr, size) {
return arr.length ? arr.reduce((total, currentValue) => (total[total.length - 1].length === size ? total.push([currentValue]) : total[total.length - 1].push(currentValue), total), [[]]) : [];
}
const arr = [1, 2, 3, 4, 5];
Chunk(arr, 2); // [[1, 2], [3, 4], [5]]
计算出现次数
function Counting(arr) {
return arr.reduce((total, currentValue) => {
total[currentValue] = (total[currentValue] || 0) + 1;
return total;
}, {})
}
const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const fruitCounts = fruits.reduce((total, currentValue) => {
total[currentValue] = (total[currentValue] || 0) + 1;
return total;
}, {});
console.log(fruitCounts);
/*
{
'apple': 3,
'banana': 2,
'orange': 1
}
*/
跟踪定位
function Position(arr, val) {
return arr.reduce((total, currentValue, currentIndex) => {
if (currentValue === val) {
total.push(currentIndex)
}
return total
}, []);
}
const arr = [2, 1, 5, 4, 2, 1, 6, 6, 7];
Position(arr, 2); // [0, 4]
组合功能
const add5 = (x) => x + 5;
const multiply3 = (x) => x * 3;
const subtract2 = (x) => x - 2;
const composedFunctions = [add5, multiply3, subtract2];
const result = composedFunctions.reduce((total, currentValue) => currentValue(total), 10);
console.log(result); // 43
阵列重复数据删除
function Uniq(arr) {
return arr.reduce((total, currentValue) => total.includes(currentValue) ? total : [...total, currentValue], []);
}
const arr = [2, 1, 0, 3, 2, 1, 2];
Uniq(arr); // [2, 1, 0, 3]
计算平均值
function Average(arr) {
return arr.reduce((total, currentValue, currentIndex, array) => {
total += currentValue;
if (currentIndex === array.length - 1) {
return total / array.length;
}
return total;
}, 0)
}
const grades = [85, 90, 92, 88, 95];
console.log(Average(grades)); // Output: 90
数组最大值和最小值
function Max(arr = []) {
return arr.reduce((total, currentValue) => total > currentValue ? total : currentValue);
}
function Min(arr = []) {
return arr.reduce((total, currentValue) => total < currentValue ? total : currentValue);
}
const arr = [12, 45, 21, 65, 38, 76, 108, 43];
Max(arr); // 108
Min(arr); // 12
URL 参数序列化
function StringifyUrlSearch(search) {
return Object.entries(search).reduce(
(total, currentValue) => `${total}${currentValue[0]}=${encodeURIComponent(currentValue[1])}&`,
Object.keys(search).length ? "?" : ""
).replace(/&$/, "");
}
const params = { foo: "bar", baz: 42 };
console.log(StringifyUrlSearch(params)); // "?foo=bar&baz=42"
对象分组
function Grouping(arr, key) {
return arr.reduce((total, currentValue) => {
if (!total[currentValue[key]]) {
total[currentValue[key]] = [];
}
total[currentValue[key]].push(currentValue);
return total;
}, {});
}
const people = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 25 },
{ name: 'Dave', age: 30 }
];
console.log(Grouping(people, 'age'));
/*
{
'25': [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }],
'30': [{ name: 'Bob', age: 30 }, { name: 'Dave', age: 30 }]
}
*/
创建查询地图
function arrayToMap(arr, key) {
return arr.reduce((total, currentValue) => {
total[currentValue[key]] = currentValue;
return total;
}, {})
}
const products = [
{ id: 1, name: 'Laptop', price: 999 },
{ id: 2, name: 'Phone', price: 699 },
{ id: 3, name: 'Tablet', price: 499 },
];
const productMap = arrayToMap(product, 'id');
console.log(productMap);
/*
{
'1': { id: 1, name: 'Laptop', price: 999 },
'2': { id: 2, name: 'Phone', price: 699 },
'3': { id: 3, name: 'Tablet', price: 499 }
}
*/
// Accessing a product by ID
const laptop: Product = productMap[1];
console.log(laptop); // { id: 1, name: 'Laptop', price: 999 }
将多个数组合并为一个对象
function Merge(arr1, arr2) {
return arr1.reduce((total, currentValue, index) => {
total[currentValue] = arr2[index];
return total;
}, {})
}
const keys = ['name', 'age', 'gender'];
const values = ['Alice', 25, 'female'];
console.log(person); // { name: 'Alice', age: 25, gender: 'female' }
检查字符串是否为回文字符串
回文字符串:是一个正读和反读都一样的字符串。
function isPalindrome(str) {
return str.split('').reduce((total, currentValue, index, array) => {
return total && currentValue === array[array.length - index - 1];
}, true)
}
const str = 'racecar';
console.log(isPalindrome(str)); // Output: true