假設有這樣一個數組: 我們想去掉數組中id重覆的對象,比如同樣id為2的兩個對象—— 我們該如何去做呢? 事實上,對於數組對象,傳統的去重方法無能為力,至於forEach()、filter()等迭代方法也不好使;真正能做到優雅去重的,是ES5新增加的一個方法——reduce() 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: "小陳"} (去掉任何一個都可以)
我們該如何去做呢?
事實上,對於數組對象,傳統的去重方法無能為力,至於forEach()、filter()等迭代方法也不好使;真正能做到優雅去重的,是ES5新增加的一個方法——reduce()
reduce()方法接收一個回調函數作為第一個參數,回調函數又接受四個參數,分別是:
1.previousValue => 初始值或上一次回調函數疊加的值;
2. currentValue => 本次回調(迴圈)將要執行的值;
3. index =>“currentValue”的索引值;
4. arr => 數組本身;
reduce()方法返回的是最後一次調用回調函數的返回值;
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個對象