当前位置:首页 » 《关于电脑》 » 正文

JS 中 reduce()方法及使用详解

7 人参与  2024年09月07日 15:26  分类 : 《关于电脑》  评论

点击全文阅读


reduce()方法很强大,在很多时候都可以用到,这篇文章将会以十二种场景来演示它的使用方法,这将涵盖其90%以上的场景。还有很重要的一点,相信我,90%以上的人都不能熟练的运用reduce方法,所以掌握了它,你就可以出去装杯了哈哈。

1. 语法介绍

reduce()方法的基础语法如下:

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

其中,arr是调用reduce()方法的数组。这个方法执行一个“reducer”回调函数(callback)在数组的每个元素上,最终将它们“归纳”为一个单一的输出值。

reduce()方法接受两个参数:

callback函数:在数组的每一项上执行的函数,接受四个参数: accumulator:累加器累积回调的返回值。currentValue:当前处理的数组元素。index(可选):当前处理的数组元素的索引。array(可选):调用reduce()方法的数组本身。 initialValue(可选):作为第一次调用callback函数时accumulator参数的值。

2. 分析参数

accumulatorcurrentValue

accumulator是一个“累加器”,它是callback函数从数组的第一项到当前项的累积返回值。在reduce()的第一次调用中,accumulator可以是initialValue(如果提供了此参数),或者是数组的第一个元素(如果没有提供initialValue)。

currentValue是数组中正在处理的当前元素。在reduce()的迭代过程中,它依次表示数组的每一个元素。

indexarray

index是可选参数,表示currentValue在数组中的索引。reduce()的迭代从数组的第一项(或第二项,如果未提供initialValue)开始,因此index0(或1)开始。

array是可选参数,表示调用reduce()方法的数组本身,这在某些情况下用于引用整个数组。

initialValue

initialValue是可选的初始值。提供initialValue时,accumulator将从这个值开始累积;否则,accumulator将从数组的第一个元素开始累积,并且迭代从数组的第二个元素开始。

3. 注意事项

返回值

在使用reduce()时,一定要注意回调函数必须有返回值,这个返回值将被用作下一次迭代的accumulator值。如果回调函数没有返回值,那么accumulator将会是undefined,这可能会导致逻辑错误。

空数组

对空数组使用reduce()时,如果没有提供initialValue,则会抛出TypeError。因此,当你不确定数组是否为空时,需要提供initialValue

性能

尽管reduce()非常强大,但在处理大型数组或复杂的迭代逻辑时,应考虑其对性能的影响。在某些情况下,其他方法(如循环)可能更高效。

言归正传,接下来展示15种使用场景!

1. 数组求和与求积

// 数组求和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

2. 计算数组对象中某属性的总和

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

3. 实现数组的平均值计算

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

4. 数组去重

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]

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 }

6. 统计数组元素出现的次数

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 }

7. 找出数组中的最大值或最小值

// 最大值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

8. 分组

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 }]}*/

9. 链式调用函数

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

10. 展平数组

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]### 11. 实现Promise串行执行```javascriptconst 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!'));

12. 对象属性求和

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

13. 构造查询字符串

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"

14. 条件累加

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

15. 实现自定义的map()filter()

// 自定义 map 使用 reduceconst 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 使用 reduceconst 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]

点击全文阅读


本文链接:http://zhangshiyu.com/post/156733.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1