1、reduce介绍 它可以用来求和、求积、统计元素出现次数、数组去重等。
array.reduce((prev, cur, index, arr)=> {
/***/
}, initialValue)
reduce 为数组中的每一个元素依次执行回调函数,接受四个参数:初始值 initialValue(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。
参数一: callback 函数(执行数组中每个值的函数,包含四个参数):
prev 必需 (上一次调用回调返回的值,或者是提供的初始值(initialValue))累加器累积回调的返回值。
cur 必需(当前处理的数组元素)
index 可选 (当前元素在数组中的索引)
arr 可选 调用 reduce 的数组本身
参数二:
initialValue是可选的初始值。提供initialValue时,prev 将从这个值开始累积;否则,prev 将从数组的第一个元素开始累积,并且迭代从数组的第二个元素开始。
- 数组求和与求积
// 数组求和
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((total, value) => total + value, 0);
console.log(sum); // 输出: 10
// 数组求积
const product = numbers.reduce((total, value) => total * value, 1);
console.log(product); // 输出: 24
- 计算数组对象中某属性的总和
const items = [
{ name: 'Book', price: 15 },
{ name: 'Pen', price: 5 },
{ name: 'Notebook', price: 20 }
];
const total = items.reduce((sum, item) => sum + item.price, 0);
console.log(total); // 输出: 40
- 实现数组的平均值计算
const grades = [87, 94, 68, 100];
const average = grades.reduce((total, grade, index, array) => {
total += grade;
if (index === array.length - 1) {
return total / array.length;
} else {
return total;
}
}, 0);
console.log(average); // 输出: 87.25
- 数组去重
const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = numbers.reduce((unique, item) => {
return unique.includes(item) ? unique : [...unique, item];
}, []);
console.log(uniqueNumbers); // 输出: [1, 2, 3, 4, 5]
- 将数组转换为对象
const fruits = ['apple', 'banana', 'cherry'];
const fruitObj = fruits.reduce((obj, fruit, index) => {
obj[fruit] = index;
return obj;
}, {});
console.log(fruitObj); // 输出: { apple: 0, banana: 1, cherry: 2 }
- 统计数组元素出现的次数
const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
const nameCount = names.reduce((count, name) => {
count[name] = (count[name] || 0) + 1;
return count;
}, {});
console.log(nameCount); // 输出: { Alice: 2, Bob: 1, Tiff: 1, Bruce: 1 }
- 找出数组中的最大值或最小值
// 最大值
const numbersMax = [10, 5, 100, 2, 1000];
const max = numbersMax.reduce((a, b) => Math.max(a, b));
console.log(max); // 输出: 1000
// 最小值
const numbersMin = [10, 5, 100, 2, 1000];
const min = numbersMin.reduce((a, b) => Math.min(a, b));
console.log(min); // 输出: 2
- 分组
const people = [
{ name: 'Alice', age: 21 },
{ name: 'Max', age: 20 },
{ name: 'Jane', age: 20 }
];
const groupByAge = people.reduce((group, person) => {
const { age } = person;
if (!group[age]) {
group[age] = [];
}
group[age].push(person);
return group;
}, {});
console.log(groupByAge);
/*
输出:
{
20: [{ name: 'Max', age: 20 }, { name: 'Jane', age: 20 }],
21: [{ name: 'Alice', age: 21 }]
}
*/
- 链式调用函数
const increment = x => x + 1;
const double = x => x * 2;
const functions = [increment, double];
const result = functions.reduce((value, func) => func(value), 3);
console.log(result); // 输出: 8
- 展平数组
const nestedArray = [1, [2, [3, [4,5]]], 6];
const flatArray = nestedArray.reduce((acc, val) => acc.concat(Array.isArray(val) ? flattenArray(val) : val), []);
console.log(flatArray); // 输出: [1, 2, 3, 4, 5, 6]
//另外一种写法,用 Array.flat()
const nestedArray = [1, [2, [3, [4, 5]]], 6];
const flatArray = nestedArray.flat(Infinity);
console.log(flatArray); // 输出: [1, 2, 3, 4, 5, 6]
- 实现Promise串行执行
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const tasks = [delay(1000), delay(2000), delay(3000)];
tasks.reduce((prev, task) => {
return prev.then(() => task);
}, Promise.resolve()).then(() => console.log('All tasks completed!'));
- 对象属性求和
const result = [
{ subject: 'math', score: 78 },
{ subject: 'english', score: 82 },
{ subject: 'science', score: 95 }
];
const totalScore = result.reduce((total, current) => total + current.score, 0);
console.log(totalScore); // 输出: 255
- 构造查询字符串
const params = { name: 'John', age: 30, city: 'New York' };
const queryString = Object.entries(params).reduce((str, [key, value], index) => {
const delimiter = index === 0 ? '?' : '&';
return `${str}${delimiter}${key}=${value}`;
}, '');
console.log(queryString); // 输出: "?name=John&age=30&city=New York"
- 条件累加
const numbers = [1, 2, 3, 4, 5, 6];
const evenSum = numbers.reduce((sum, num) => {
return num % 2 === 0 ? sum + num : sum;
}, 0);
console.log(evenSum); // 输出: 12
- 实现自定义的map()或filter()
// 自定义 map 使用 reduce
const numbersMap = [1, 2, 3, 4, 5];
const doubled = numbersMap.reduce((acc, cur) => {
acc.push(cur * 2);
return acc;
}, []);
console.log(doubled); // 输出: [2, 4, 6, 8, 10]
// 自定义 filter 使用 reduce
const numbersFilter = [1, 2, 3, 4, 5];
const evens = numbersFilter.reduce((acc, cur) => {
if (cur % 2 === 0) {
acc.push(cur);
}
return acc;
}, []);
console.log(evens); // 输出: [2, 4]
14.数字千分化
function ThousandNum(num = 0) {
const str = (+num).toString().split(".");
const int = nums => nums.split("").reverse().reduceRight((t, v, i) => t + (i % 3 ? v : `${v},`), "").replace(/^,|,$/g, "");
const dec = nums => nums.split("").reduce((t, v, i) => t + ((i + 1) % 3 ? v : `${v},`), "").replace(/^,|,$/g, "");
return str.length > 1 ? `${int(str[0])}.${dec(str[1])}` : int(str[0]);
}
ThousandNum(1234); // "1,234"
ThousandNum(1234.00); // "1,234"
ThousandNum(0.1234); // "0.123,4"
ThousandNum(1234.5678); // "1,234.567,8"
15、反转
function ReverseStr(str = "") {
return str.split("").reduceRight((t, v) => t + v);
}
const str = "reduce最牛逼";
ReverseStr(str); // "逼牛最ecuder"