「查缺补漏」女朋友问我能不能给她讲讲reduce

2,908 阅读4分钟

前言

女朋友问我能不能给她讲讲reduce,想想之前对reduce理解的也不是很深刻,这次正好趁着给她讲解的功夫自己也巩固一下。

语法

arr.reduce(callback, [initialValue])

reduce为数组中的每个元素依次执行callback函数,不包括数组中被删除或从未被赋值的元素,callback函数接收四个参数:

  • accumulator 累计器
  • currentValue 当前值
  • currentIndex 当前索引
  • array 数组

initialValue

initialValue是可选值,看似不太重要,但是对accumulator和currentValue却有着很重要的影响。

当initialValue不存在时

let arr = [1, 2, 3, 4];
let sum = arr.reduce((acc, cur, index)=>{
 console.log(acc, cur, index);
 return acc + cur;
});
console.log(sum)

输出结果为:

1 2 1
3 3 2
6 4 3
10

从上述例子可以看出,当initialValue不存在时,当第一次循环时accumulator为数组的第一个元素,currentValue为数组的第二个元素,之后的循环accumulator为前一个循环的return返回值,currentValue为之后的元素,数组总共有4个元素,但是只循环了三次。

当存在initialValue时

let arr = [1, 2, 3, 4];
let sum = arr.reduce((acc, cur, index)=>{
 console.log(acc, cur, index);
 return acc + cur;
}, 0);
console.log(sum);

输出结果为:

0 1 0
1 2 1
3 3 2
6 4 3
10

上述例子可以看出,当initialValue存在时,在第一次循环时accumulator为initialValue的值,currentValue为数组的第一个值,之后的循环accumulator为前一个循环的return返回值,currentValue为之后的元素,数组总共有4个元素,就执行了4次循环。

当数组为空时

let arr = [];
let sum = arr.reduce((acc, cur, index)=>{
 return acc + cur;
})
//报错,"TypeError: Reduce of empty array with no initial value"
let arr = [];
let sum = arr.reduce((acc, cur, index)=>{
 return acc + cur;
}, 0)
console.log(sum); // 0

当数组为空时,没有写initialValue参数,会直接报错,所以以防万一,尽量填写initialValue。

reduce的应用

循循环有很多种,为什么要应用reduce?难道是为了提高逼格嘛!!!其实不排除这种可能😂 接下来讲解一些reduce的骚操作:

1、求和

let arr = [1, 2, 3, 4, 5, 6];
let sum = arr.reduce((acc, cur)=>{
 return acc + cur;
}, 0)
console.log(sum); 

2、二维数组降为一维数组

let arr = [[1, 2], [3, 4], [5, 6]];
let flattened = arr.reduce((acc, cur)=>{
 return acc.concat(cur);
}, [])

3、计算数组中每个元素出现的次数

话说这个问题当时面试的时候遇到过,求的是一篇英文文章中,字母出现的次数,其实跟这个差不多,当时写的很复杂,现在想想如果当初选择了这个方法就会好很多。

let names = ['James', 'Bob', 'Alice', 'Bob', 'John'];
let countedNames = names.reduce((acc, cur)=>{
 if (cur in acc) {
  acc[cur]++;
 } else {
  acc[cur] = 1;
 }
 return acc;
}, {})

4、按属性对object分类

let people = [
 {name: 'Alice', age: 21},
 {name: 'James', age: 20},
 {name: 'John', age: 20}
];
const groupBy = (objectArray, property)=>{
 return objectArray.reduce((acc, cur)=>{
  let key = cur[property];
  if (!acc[key]) {
   acc[key] = [];
  }
  acc[key].push(cur);
  return acc;
 }, {})
};
let gruopedPeople = groupBy(people, ‘age’);

5、数组去重

let arr = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5];
let result = arr.reduce((acc, cur)=>{
 if (!acc.includes(cur)) {
  acc.push(cur);
 } 
 return acc;
}, [])

6、redux中的compose函数

官方代码如下:

export default function compose(...funcs) {
 if (funcs.length === 0) {
  return arg => arg;
 }
 if (funcs.length === 1) {
  return funcs[0];
 }
 return funcs.reduce((a, b)=>(...args)=>a(b(....args)));
}

compose的返回值还是一个函数,调用这个函数所传递的参数将会作为compose最后一个参数的参数,由内向外,逐步调用。 reduce执行过程:

funcs = [f1, f2, f3];
loop1: a = f1, b = f2, ret1 = (...args) => f1(f2(...args))
loop2: a = ret1, b = f3, ret2 = (...args) => ret1(f3(...args)) , 即 ret2 = (...args) => f1(f2(f3(...args)))

后语

觉得还可以的,麻烦走的时候能给点个赞,大家一起学习和探讨!

还可以关注我的博客希望能给我的github上点个Start,小伙伴们一定会发现一个问题,我的所有用户名几乎都与番茄有关,因为我真的很喜欢吃番茄❤️!!!

想跟车不迷路的小伙还希望可以关注公众号 前端老番茄 或者扫一扫下面的二维码👇👇👇。关注后我拉你进前端进阶群,大家一起交流,一起学习,还可以获取免费的资料哦!!! 我是一个编程界的小学生,您的鼓励是我不断前进的动力,😄希望能一起加油前进。

本文使用 mdnice 排版