昨天在 FB 社團看到有人提問:1
2
3
4
5
6let arr = [
{ name: "alex", value: 10 },
{ name: "alex", value: 20 },
{ name: "tom", value: 30 },
{ name: "tom", value: 40 }
];
想變成1
2
3
4let arr = [
{ name: "alex", value: 10 },
{ name: "tom", value: 30 }
];
想了一陣子想到用Set
&Filter
來處理..
去除某物件屬性重複值
針對題目的需求是只要重複name
的第一筆資料,
透過Set
來達到去重複的功能並透過filter
來獲取結果陣列:1
2
3
4
5
6
7
8
9
10const arr = [
{name:'alex',value:10},
{name:'alex',value:20},
{name:'tom',value:30},
{name:'tom',value:40}
];
const set = new Set();
const result = arr.filter(item => !set.has(item.name) ? set.add(item.name) : false);
console.log(result);
// [{name: "alex", value: 10}, {name: "tom", value: 30}]
第一步先建立一個set
來當篩選的容器,
在filter
裡頭判斷,如果set
裡面沒有循環到的name
,
就新增進去,再新增的同時因為filter的特性是會把retun true
的內容回傳為新的陣列,
箭頭函示不加大括號的情況下會等同於return
,在這個情境下等於回傳了一個動作(此動作是成立的,是true)。
去除重複的物件
如果要針對整個陣列物件中去除重複物件的話可以透過JSON.stringify
來做:1
2
3
4
5
6
7
8
9const arr = [
{name:'a', value:10},
{name:'a', value:20},
{name:'a', value:20},
{name:'b', value:30},
];
const result = [...new Set(arr.map(item => JSON.stringify(item)))].map(item => JSON.parse(item));
console.log(result);
// [{name: "a", value: 10}, {name: "a", value: 20}, {name: "b", value: 30}]
弄成一行看起來好像比較厲害(?)XD
因為物件跟物件之間無法比較,所以想法是透過轉字串來比較,
第一步先使用new Set
並透過map
&JSON.stringify
把每一個陣列內的物件轉為字串,
再透過展開運算符[...]
來把剛才Set
的結果轉為陣列,
最後再用一次map
把裡面的物件字串透過JSON.parse
再轉回物件。
取得重複的物件
剛才都是去除重複,那如果是要抓出重複的物件有哪些呢?
把邏輯反轉過來:1
2
3
4
5
6
7
8
9
10
11
12
13const arr = [
{name:'a', value:10},
{name:'a', value:20},
{name:'a', value:20},
{name:'b', value:30},
{name:'b', value:40},
{name:'b', value:40}
];
const set = new Set();
const result = arr.filter(item => set.has(JSON.stringify(item)) ? true : (set.add(JSON.stringify(item)), false));
console.log(result);
//[{name: "a", value: 20}, {name: "b", value: 40}]
這裡跟前面的差不多道理,比較特別在三元運算子的部分,
同前面提到的,filter的特性是會將return true
的內容加入,
所以如果單純寫1
set.has(JSON.stringify(item)) ? true : set.add(JSON.stringify(item))
這樣的話也會被新增進去,因為set.add(JSON.stringify(item))
也是個true
的動作,
所以使用(set.add(JSON.stringify(item)), false)
來讓新增動作執行後,
再回傳false
阻止filter
的新增。
其實寫清楚一點就是下面這樣,不過就是會想試試一行寫完的方法XD
1
2
3
4
5
6
7 const result = arr.filter(item => {
if (set.has(JSON.stringify(item))) {
return true;
} else {
set.add(JSON.stringify(item));
}
});
其他
以上都是自己邊試邊理解的,如果有錯誤或更好的寫法也請再告知:D!