从给数组中的对象去重看Javascript中的reduce()

假设有这样一个数组:数组

let person = [ {id: 0, name: "小明"}, {id: 1, name: "小张"}, {id: 2, name: "小李"}, {id: 3, name: "小孙"}, {id: 1, name: "小周"}, {id: 2, name: "小陈"}, ]

咱们想去掉数组中id重复的对象,好比一样id为2的两个对象——函数

{id: 2, name: "小李"}和{id: 2, name: "小陈"} (去掉任何一个均可以)

咱们该如何去作呢?spa

事实上,对于数组对象,传统的去重方法无能为力,至于forEach()、filter()等迭代方法也很差使;真正能作到优雅去重的,是ES5新增长的一个方法——reduce()code

reduce()方法接收一个回调函数做为第一个参数,回调函数又接受四个参数,分别是:对象

 

1.previousValue => 初始值或上一次回调函数叠加的值;blog

2. currentValue => 本次回调(循环)将要执行的值;索引

3. index =>“currentValue”的索引值;回调函数

4. arr => 数组自己;it

 reduce()方法返回的是最后一次调用回调函数的返回值io

let log = console.log.bind(console); let arr = [1,2,3,4,5,6]; arr = arr.reduce((previousValue, currentValue) => { return previousValue + currentValue; //返回的是最后一次调用回调函数的值,15+6; }) log(arr); // 21

能够看出,上面代码的最终结果就是1+2+3+4+5+6 = 21;

此外,reduce还能够接收第二参数initialValue,用来声明回调函数(第一个参数)的previousValue的类型和初始值

let log = console.log.bind(console); let arr = [1,2,3,4,5,6]; arr = arr.reduce((previousValue,currentValue) => { return previousValue + currentValue; },0) //指定cur的类型为Number而且初始值为0,当设为1时,最终打印的值为22
log(arr); // 21

 

须要注意的是,若是设置了initialValue的值,第一次执行回调函数的previousValue的值等于initialValue,此时查看当前索引(index)为0;但若是不设置initialValue的值,previousValue的值为数组的第一项,而且索引值(index)为1;也就是说,不设置初始值的话reduce()方法实际是从第二次循环开始的!

如今让咱们回到文章开头的那个数组:

let log = console.log.bind(console); let person = [ {id: 0, name: "小明"}, {id: 1, name: "小张"}, {id: 2, name: "小李"}, {id: 3, name: "小孙"}, {id: 1, name: "小周"}, {id: 2, name: "小陈"}, ]; let obj = {}; person = person.reduce((cur,next) => { obj[next.id] ? "" : obj[next.id] = true && cur.push(next); return cur; },[]) //设置cur默认类型为数组,而且初始值为空的数组 log(person);

打印person后,咱们就能够获得去重后的数组。

固然, redecu()除了累加和去重外,功能还有不少,好比能够扁平化多维数组——

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
    return a.concat(b);
}, []); // [0,1,2,3,4,5]

 

再说句题外的,提到去重,不少人都会想到ES6的Set;不过根据个人实验,Set仍是适合对基本类型的去重,若是Set中的每一项是对象的话,是不会去重的,j即便有的对象如出一辙——

let arr = new Set([
    {id: 0, name: "小明"},
    {id: 0, name: "小明"},
    {id: 0, name: "小明"},
    {id: 0, name: "小明"}      
]);
console.log([...arr]); //依旧是这4个对象
相关文章
相关标签/搜索