用 Array 实现 Set
Set 是什么
- Set 是 ES6 提供的新的数据结构
- Set 相当于自带去重功能的 Array
- Set 本身是一个构造函数
Set 的用途
Set 的用途只有一个: 去重
字符串去重
// 方法1:
const str = "hello world";
const uniq1 = [...new Set(str)].join("");
console.log(uniq1); // helo wrd
// 方法2:
const strArr = str.split("");
const uniq2 = _.uniq(strArr).join("");
console.log(uniq2); // helo wrd
一维数组去重
// 方法1:
const arr = [1, 2, 2, 3, 3, 3, 4, 5];
const uniq1 = [...new Set(arr)];
console.log(uniq1); // [1, 2, 3, 4, 5]
// 方法2:
const uniq2 = _.uniq(arr);
console.log(uniq2); // [1, 2, 3, 4, 5]
二维数组去重
const arr = [
{ id: 1001, name: "张三" },
{ id: 1002, name: "李四" },
{ id: 1002, name: "李四" },
{ id: 1002, name: "李四" },
{ id: 1003, name: "王五" },
{ id: 1003, name: "王五" },
{ id: 1003, name: "王五" },
{ id: 1003, name: "王五" },
{ id: 1004, name: "赵六" },
];
// 方法1: (无法实现)
const uniq1 = [...new Set(arr)];
console.log(uniq1); // 输出 arr, 未达到去重效果
// 方法2:
const uniq2 = _.uniqBy(arr, item => item.id);
console.log(JSON.stringify(uniq2)); // [{"id":1001,"name":"张三"},{"id":1002,"name":"李四"},{"id":1003,"name":"王五"},{"id":1004,"name":"赵六"}]
实现 Set
以下是示例代码, MySet 只考虑了入参是 Array 的情况
class MySet {
constructor(array) {
this.set = _.uniq(array || []);
}
get size() {
return this.set.length;
}
add(value) {
this.set = _.uniq([...this.set, value]);
}
delete(value) {
this.set = this.set.filter((item) => item !== value);
}
has(value) {
return this.set.includes(value);
}
clear() {
this.set = [];
}
keys() {
// Set 没有键名, keys 和 values 的行为完全一致
return this.set;
}
values() {
return this.set;
}
entries() {}
forEach(iteratee) {
this.set.forEach(iteratee);
}
print(prefix) {
console.log(prefix, ":", this.set);
}
}
const arr = [1, 2, 2, 3, 3, 3, 4, 5];
const s = new MySet(arr);
s.print("Step1"); // [1, 2, 3, 4, 5]
s.add(6);
s.add(6);
s.print("Step2"); // [1, 2, 3, 4, 5, 6]
s.delete(1);
s.print("Step3"); // [2, 3, 4, 5, 6]
console.log(s.has(1)); // false
s.forEach((item) => {
console.log(`Step4: ${item}`);
});
s.clear();
s.print("Step5"); // []
Set 和 WeakSet
WeakSet 和 Set 类似, 区别在于:
- WeakSet 的成员只能是对象
- WeakSet 中的对象是弱应用, 可能被垃圾回收

浙公网安备 33010602011771号