JS笔记《Set与WeakSet数据结构》

39 阅读3分钟

Set 概述

  • Set是一种类似数组的数据结构,但是成员的值都是唯一的,没有重复的。内部判断值是否唯一采用的是类似于严格相等的算法,唯一不同的是严格相等NaN不等于自身,而set中认为是相等的。
const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
  console.log(i); // 2 3 5 4
}
  • 可以接收一个数组(或者具有Iterator接口的其他数据结构)作为参数,用来初始化。
const set = new Set([1, 2, 3, 4, 4]);
[...set]   // [1, 2, 3, 4]

const set = new Set(document.querySelectorAll('div'));  // 类数组,具有Iterator接口
set.size  // 31
  • 可以实现数组去重
const arr = [2, 3, 5, 4, 5, 2, 2];
[...new Set(arr)]  // [2, 3, 5, 4]

实例属性

constructor

  • 指向构造函数,返回Set函数。

size

  • 返回Set实例的成员总数。
const set = new Set([1, 2, 3, 4, 4]);
set.size  // 4  重复的被删除了

实例操作方法

add()

  • 添加某个值,返回Set结构本身。
const set = new Set();
set.add(1)  // Set(1) {1}

delete()

  • 删除某个值,返回一个布尔,表示删除是否成功。
const set = new Set();
set.add(1)  // Set(1) {1}

set.delete(1) // true
set.delete(1) // false
set  // Set(0) {size: 0}

has()

  • 返回一个布尔值,表示该值是否为Set成员。
const set = new Set();
let obj = {};
set.add(obj);

set.has(obj);  // true

clear()

  • 清除所有成员,没有返回值。
const set = new Set();
let obj = {};
set.add(obj);

set.clear()

实例遍历方法

  • Set的遍历顺序就是插入顺序。keys()values()entries()返回的都是遍历器对象(Iterator)。

keys()

  • 返回键名的遍历器。

values()

  • 返回键值的遍历器。

entries()

  • 返回键值对的遍历器。
let set = new Set(['red', 'green', 'blue']);

set.keys()   // SetIterator {'red', 'green', 'blue'} 
// 由于set键名和键值一致,所以keys与values方法一致

set.values() // SetIterator {'red', 'green', 'blue'}

set.entries() // SetIterator {'red' => 'red', 'green' => 'green', 'blue' => 'blue'}
// 键名和键值一致


for (let item of set.keys()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.values()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.entries()) {
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

forEach()

  • 使用回调函数遍历每个成员。Set结构的键名就是键值,因此参数一与参数二的值永远都是一样的。
```js
let set = new Set(['red', 'green', 'blue']);

set.forEach((item, index) => {
   console.log(item, index)
})
// red red
// green green
// blue blue
  • 也可以使用for of直接遍历set
let set = new Set(['red', 'green', 'blue']);

for (let x of set) {
  console.log(x);
}
// red
// green
// blue

Set 求并、交、差集

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);

// 并集(两集合全部的元素)
let union = new Set([...a, ...b]);
union // Set(4) {1, 2, 3, 4}

// 交集(两集合公共的元素)
let intersect = [...a].filter(item => b.has(item));
intersect // [2, 3]

// 差集(取一个集合中另一集合没有的元素) 求 a 差 b
let diff = [...a].filter(item => !b.has(item));
diff // [1]

WeakSet 概述

  • Set数据结构类似,也是不重复的值的集合。区别一是WeakSet的成员只能是对象Symbol值;区别二是WeakSet中的对象都是弱引用,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet中。
  • 没有size属性,也无法遍历。
const ws = new WeakSet();
ws.add(1)   // TypeError: Invalid value used in weak set

ws.add({})  // 正确
ws.add(Symbol('foo')) // 正确

实例操作方法

add()

  • 添加一个新成员,返回WeakSet数据结构。

delete()

  • 清除 WeakSet 实例的指定成员,成功返回true,找不到返回false

has()

  • 返回一个布尔值,表示某个值是否在 WeakSet 实例之中。