實務上常會遇到 Array 雖有重複資料,但我們並不希望顯示重複部分,這個常見需求,該如何使用 ECMAScript 實現呢 ?
Version
macOS Mojave 10.14.5
VS Code 1.36.1
Quokka 1.0.236
ECMAScript 2015
Ramda 0.26.1
Set
let data = [1, 2, 3, 1];
let uniq = arr => [...new Set(arr)];
uniq(data); // ?
若使用 ES6,對於處理 primitive 重複,最簡單就是使用 set。
Set 的本意就是儲存 不重複
的 object,因此 array 傳入後,會自動移除重複部分,最後再使用 spread operator 展開成為新 array 回傳。
Array.from()
let data = [1, 2, 3, 1];
let uniq = arr => Array.from(new Set(arr));
uniq(data); // ?
也可使用 Array.from()
將 set 轉成 array。
Ramda
import { uniq } from 'ramda';
let data = [1, 2, 3, 1];
uniq(data); // ?
Ramda 已經提供 uniq()
,可直接使用。
Object
import { uniq } from 'ramda';
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
{ title: 'FP in JavaScript', price: 100 }
];
console.dir(uniq(data));
若 array 內是 object,則無法使用 set,因為 set 比較的是 object 的 reference,僅管 property 都相同,但 reference 還是不同,因此 set 視為不重複。
但 Ramda 的 uniq()
的判斷依據是 equals()
,而 equals()
比較的是 property 的 value,因此 property 相同就視為重複。
Ramda 的
uniq()
無論 primitive 或 object 都適用
Conclusion
- 若不使用 Ramda,則 set 是簡單的寫法,唯 set 僅對 primitive 有效,對 object 無效
- Set 可搭配 spread operator 或
Array.from()
- Ramda 的
uniq()
是最通用解法,無論是 primitive 或 object 都適用
Reference
Bret Cameron, 12 JavaScript Tricks You Won’t Find in Most Tutorials
Ramda, uniq()