工作中遇到了数组对象去重的问题,第一想法依旧是for循环,但是为了让自己的代码跟优雅一些,就到网上查了一下,果然已经有大佬走在前面了,既然如此那就更需要研究一下了,以下是我的理解.
-
首先在MDN上学习了以下这个函数的具体含义.reduce有四个参数分别是:
- Accumulator (acc) (累计器)
- Current Value (cur) (当前值)
- Current Index (idx) (当前索引)
- Source Array (src) (源数组)
还有一句非常经典的解释(简直完美)
您的 reduce 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
在学习的时候去使用这句话去理解,你会发现这句话简直是最好的定义,下面直接代码
1. reduce之最简单用法-----累加器
// 先定义一个都是数字的数组
const arr_number = [1, 2, 3, 4, 5, 6, 7]
// 直接使用reduce获取全部的和
sum = arr_number.reduce((acc, cur) => {
// 这里带着那句经典又完美的话去理解
return acc + cur;
})
console.log(sum); // 28
2. reduce之进阶版一 -----数组扁平化
// 先定义一个二维数组
const arr = [[1, 2, 3, 4],[1, 2]]
arr = arr.reduce((acc, cur) => {
// 这里带着那句经典又完美的话去理解
return acc.concat(cur);
}, []) // 这里的"[]"很关键
console.log(result_arr ); // [1, 2, 3, 4, 1, 2]
3.reduce进阶版二 ------求字符串中某一个出现的次数
// 先定义一个数组
const arr_str = ['a', 'a', 'd', 'a', 'a', 'b', 'a', 'b', 'a', 'b', 'g', 'g', 'f', 'e', 'd', 'b']
result = arr_str.reduce((acc, cur) => {
// 这里带着那句经典又完美的话去理解
acc[cur] ? acc[cur]++ : acc[cur] = 1
return acc;
}, {}); // 这里的"{}"很关键
console.log(result) // {a: 6, d: 2, b: 4, g: 2, f: 1, g: 2}
4.reduce高级版-----数组对象去重
// 先定义一个数组对象
const arr_obj = [{id: 1, name:'zs'}, {id: 2, name:'ls'}, {id: 3, name:'ww'}, {id: 2, name:'zs'}, {id: 1, name:'zs'}, {id: 1, name:'zs'}]
// 创建一个临时对象
let obj = {}
arr_obj_result = arr_obj.reduce((acc, cur) => {
// 这里带着那句经典又完美的话去理解
obj[cur.id] ? "": obj[cur.id] = true && acc.push(cur)
return acc;
}, []); // 这里的"[]"很关键
console.log(arr_obj_result );// [{id: 1, name:'zs'}, {id: 2, name:'ls'}, {id: 3, name:'ww'}]
5.总结
以上差不多是reduce的用法了,在最后在说明一下细节性的问题
当我们使用reduce的时候
- 1 arr.reduce((acc,cur) => {
} ),这个是最基础的用法,这个时候acc的值是数组arr的第一个值,cur是arr的第二个值 - 2 arr.reduce((acc, cur) => {
}, 0),这里的0是acc的第一个值,cur是arr的第一个值
+3 arr.reduce((acc, cur) => {
}, []),这里的"[]"是acc的第一值(空数组),cur是arr的第一个值
总的来说,若是定义acc的值,则acc的值为定义了的值,cur是arr的第一个值;若是没有定义acc则是arr的第一个值,cur则是arr的第二个值!
因为reduce的最后两个参数比较简单,这里就直接说明一下含义,第三个是当前的索引,第四个是数组本身
经典说明摘自MDN------您的 reduce 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。