远子 💖 Vina

用 Array 实现 Set

远子 â€¢  2020å¹´12月08日 â€¢ è¯„论

Set 是什么

  1. Set 是 ES6 提供的新的数据结构
  2. Set 相当于自带去重功能的 Array
  3. 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 类似, 区别在于:

  1. WeakSet 的成员只能是对象
  2. WeakSet 中的对象是弱应用, 可能被垃圾回收

我要发表看法

«-必填
«-必填,不公开