J 筆記 - ES6 Remove Array Duplicates
在 Ruby 裡面要做這件事情真的方便許多直接 uniq
就可以完成,但常常被寫好的 method
慣壞了卻想不太到 JS 裡頭該怎麼實作,所以整理一些 Remove Array Duplicates
的方法…
3 ways in ES6
總共在 ES6 裡面有 3 種方法可以實作,而我最喜歡的莫過於 Set
,又短又不用想到底裡面做了什麼,不像 filter
、reduce
,另外也覺得有點像 Ruby 的 uniq
,所以寫起來快速又實用~
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const array = ['Remove', 'Remove', 'ES5', 'ES6', 'Remove', 'ES7'];
[...new Set(array)];
array.filter((item, index) => array.indexOf(item) === index);
array.reduce((uniq, item) => uniq.includes(item) ? uniq : [...uniq, item], []);
|
1. Set
The Set object lets you store unique values of any type, whether primitive values or object references.
ES6 提供了新的數據結構 Set
。它類似於數組,但值都是唯一的,没有重複的值。
因此我們來看看到底做了什麼…
1 2 3 4 5 6 7
| const array = ['Remove', 'Remove', 'ES5', 'ES6', 'Remove', 'ES7'];
const newarray = new Set(array); console.log(newarray);
|
在結合之前前幾篇的 spread operator、Array.from 將它變成陣列
1 2 3 4 5 6 7
| const array = ['Remove', 'Remove', 'ES5', 'ES6', 'Remove', 'ES7'];
const newarray = new Set(array); const backToArray = [...newarray]; const ArrayfromtoArray = Array.from(newarray);
|
2. filter
1 2 3 4
| const array = ['Remove', 'Remove', 'ES5', 'ES6', 'Remove', 'ES7'];
array.filter((item, index) => array.indexOf(item) === index);
|
雖然這樣子就能出現答案,但中間 Array.prototype.indexOf() 是做了什麼事情呢?
The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.
1 2 3 4 5 6 7 8 9 10 11 12
| const array = ['Remove', 'Remove', 'ES5', 'ES6', 'Remove', 'ES7'];
array.filter((item, index) => { console.log( item, index, array.indexOf(item), array.indexOf(item) === index, );
return array.indexOf(item) === index });
|
item |
index |
indexOf |
condition |
Remove |
0 |
0 |
True |
Remove |
1 |
0 |
False |
ES5 |
2 |
2 |
True |
ES6 |
3 |
3 |
True |
Remove |
4 |
0 |
False |
ES7 |
5 |
5 |
True |
2.x 相反
1 2 3 4 5 6 7 8 9 10 11 12 13
| const array = ['Remove', 'Remove', 'ES5', 'ES6', 'Remove', 'ES7'];
array.filter((item, index) => { console.log( item, index, array.indexOf(item), array.indexOf(item) === index, );
return array.indexOf(item) !== index });
|
item |
index |
indexOf |
condition |
Remove |
0 |
0 |
False |
Remove |
1 |
0 |
True |
ES5 |
2 |
2 |
False |
ES6 |
3 |
3 |
False |
Remove |
4 |
0 |
True |
ES7 |
5 |
5 |
False |
3. reduce
1 2 3 4 5
| const array = ['Remove', 'Remove', 'ES5', 'ES6', 'Remove', 'ES7'];
array.reduce((uniq, item) => uniq.includes(item) ? uniq : [...uniq, item], []);
|
同上,雖然這樣子就能出現答案,但中間 Array.prototype.reduce() 是做了什麼事情呢?
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.
1 2 3 4 5 6 7 8 9 10 11 12
| const array = ['Remove', 'Remove', 'ES5', 'ES6', 'Remove', 'ES7'];
array.reduce((uniq, item) => { console.log( item, uniq, uniq.includes(item), uniq.includes(item) ? uniq : [...uniq, item], ); return uniq.includes(item) ? uniq : [...uniq, item] }, []);
|
item |
Accumulator (BEFORE Reducer Function) |
Push to Accumulator? |
Accumulator (AFTER Reducer Function) |
Remove |
[] |
Yes |
[‘Remove’] |
Remove |
[‘Remove’] |
NO |
[‘Remove’] |
ES5 |
[‘Remove’] |
Yes |
[‘Remove’, ‘ES5’] |
ES6 |
[‘Remove’, ‘ES5’] |
Yes |
[‘Remove’, ‘ES5’, ‘ES6’] |
Remove |
[‘Remove’, ‘ES5’, ‘ES6’] |
No |
[‘Remove’, ‘ES5’, ‘ES6’] |
ES7 |
[‘Remove’, ‘ES5’, ‘ES6’] |
Yes |
[‘Remove’, ‘ES5’, ‘ES6’, ‘ES7’] |
參考資料