[資料結構] —  Set

Set 是 JavaScript ES6 中新增的資料結構,Set 與陣列很類似,允許任何型態的值,跟陣列不同的是所有的值都是唯一的,不允許有重複的值,因此很適合用來去除重複的值。

宣告一個新 Set

1
2
let set = new Set();
let set2 = new Set([1, 3, 5, 7]); //{1, 3, 5, 7}

Set.add(value)

新增 value

1
set.add(1); // {1}

這邊要特別注意,因為 set 不允許有重複的值 ,所以重複 add 同個元素是不會有效果的

1
2
set.add(1); // {1}
set.add(1); // {1} 依然只有一個 1

因為 add 會回傳 set 的本身,所以可以使用 chaining(鏈)的寫法

1
set.add(1).add(2).add(3);

Set.has(value)

確認 Set 是否有該值,回傳 boolean 值

1
set.has(1); // return true

Set.delete(value)

刪除該 value,如果刪除成功會回傳 true,失敗則是 false

1
set.delete(1); // return true

Set.size

回傳 set 的長度

1
2
3
4
5
6
let set = new Set();
set.add(1);
set.add(2);
set.add(3);

set.size; //3

Set.clear()

清除 set 所有的內容,不會回傳值

1
set.clear();

Set Iteration (迭代)

  • Set.keys():由於 set 沒有 key,所以會回傳所有的 value
  • Set.values():回傳 set 所有的 value
  • Set.entires():回傳每個元素[key, value]鍵值對的內容,但因為 set 沒有 key,所以會回傳[value, value]
  • Set.forEach((value, key)=>{}):遍歷 set
1
2
3
4
5
6
7
8
let set = new Set([1, 3, 5]);

set.keys(); // {1, 3, 5}
set.values(); // {1, 3, 5}
set.entires(); // {1 => 1, 3 => 3, 5 => 5}
set.forEach((value, key) => {
console.log("value:", value, "key:", key);
});

將 Set 轉換成 👉Array

1
let array = \[...set\]

將 Array 轉換成 👉Set

1
let set = new Set(array);

所以藉由 Set 值不重複的特性,如果想去除重複的值可以這麼做

1
2
3
let arr = [1, 2, 2, 3, 1];
let set = new Set(arr); // {1, 2, 2, 3, 1}
let result = [...set]; // [1, 2, 3]

或者想找出兩個陣列的聯集

1
2
3
4
let arr1 = [1, 2, 5, 7, 9];
let arr2 = [1, 3, 4, 7, 8];
let same = new Set([...arr1, ...arr2]);
// {1, 2, 5, 7, 9, 3, 4, 8}

WeakSet

WeakSet 結構類似於 Set,但跟 Set 不同的是,不接受基本資料型態的值,只接受 Object,沒有遍歷和 size 的方法,只有 add、has、delete 這三個方法可以使用,另外,WeakSet 裡面的物件是 Weakly Reference。

甚麼是 Weakly Reference?

中文翻作弱引用,不會被垃圾回收機制計入參考,也就是說當其它物件不再參考該物件,就會被 js 的垃圾回收機制回收掉釋放記憶體,即使物件還在 WeakSet 裡面,可以必免 memery leak(記憶體洩漏)的問題。

1
2
3
4
5
6
let weakSet = new WeakSet();
weakSet.add({});
weakSet.add([]);
//{[], {}}
weakSet.add(5);
// TypeError: Invalid value used in weak set

參考資料: Set 和 Map 数据结构