ES6 Set 数据结构用法总结

发布于:2025-02-10 ⋅ 阅读:(73) ⋅ 点赞:(0)

1. Set 基本概念

Set 是 ES6 提供的新的数据结构,类似于数组,但成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。

1.1 基本用法

// 创建一个空Set
const set = new Set();

// 创建一个带有初始值的Set
const set1 = new Set([1, 2, 3, 4, 4]); // {1, 2, 3, 4}

// 从字符串创建Set
const set2 = new Set('hello'); // {'h', 'e', 'l', 'o'}

// Set的大小
console.log(set1.size); // 4

1.2 Set的基本方法

const set = new Set();

// 添加元素
set.add(1);
set.add(2).add(3); // 支持链式调用

// 删除元素
set.delete(1);

// 检查元素是否存在
console.log(set.has(2)); // true

// 清空Set
set.clear();

// 获取Set的大小
console.log(set.size); // 0

Set 是 ES6 提供的一种新的数据结构,它类似于数组,但 元素唯一,不能重复。

let mySet = new Set();
mySet.add(1);
mySet.add(2);
mySet.add(2); // 不会添加重复元素
console.log(mySet); // Set {1, 2}

Set 的常用方法

方法 说明
add(value) 添加元素
delete(value) 删除元素
has(value) 检查是否存在
clear() 清空集合
size 获取元素个数
console.log(mySet.has(1)); // true
mySet.delete(1);
console.log(mySet.has(1)); // false
console.log(mySet.size); // 1
mySet.clear();
console.log(mySet.size); // 0

2. Set的遍历

2.1 遍历方法

const set = new Set(['red', 'green', 'blue']);

// keys() - 返回键名的遍历器
for (let item of set.keys()) {
  console.log(item);
}

// values() - 返回键值的遍历器
for (let item of set.values()) {
  console.log(item);
}

// entries() - 返回键值对的遍历器
for (let item of set.entries()) {
  console.log(item);
}

// forEach() - 使用回调函数遍历每个成员
set.forEach((value, key) => console.log(value, key));

2.2 与数组的转换

// Set转数组
const set = new Set([1, 2, 3]);
const array = [...set];
// 或者
const array2 = Array.from(set);

// 数组转Set
const arr = [1, 2, 3];
const set2 = new Set(arr);

Set 结构支持多种遍历方式。

(1) for…of 遍历
let set = new Set(["apple", "banana", "cherry"]);
for (let item of set) {
  console.log(item);
}
(2) forEach 遍历
set.forEach(value => console.log(value));
(3) 使用 keys()values()entries()
let set = new Set([1, 2, 3]);
console.log([...set.keys()]); // [1, 2, 3]
console.log([...set.values()]); // [1, 2, 3]
console.log([...set.entries()]); // [[1,1], [2,2], [3,3]]

📌 keys()values() 作用相同,因为 Set 只有值,没有键。

3. 实际应用场景

3.1 数组去重

// 基本数组去重
const array = [1, 2, 2, 3, 3, 4, 5, 5];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // [1, 2, 3, 4, 5]

// 对象数组去重
const objArray = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 1, name: 'John' }
];

const uniqueObjArray = [
  ...new Set(objArray.map(JSON.stringify))
].map(JSON.parse);

3.2 交集、并集、差集操作

const set1 = new Set([1, 2, 3, 4]);
const set2 = new Set([3, 4, 5, 6]);

// 并集
const union = new Set([...set1, ...set2]);
console.log([...union]); // [1, 2, 3, 4, 5, 6]

// 交集
const intersection = new Set(
  [...set1].filter(x => set2.has(x))
);
console.log([...intersection]); // [3, 4]

// 差集
const difference = new Set(
  [...set1].filter(x => !set2.has(x))
);
console.log([...difference]); // [1, 2]

3.3 用户访问记录

class UserVisitTracker {
  constructor() {
    this.visitedPages = new Set();
  }

  recordVisit(page) {
    this.visitedPages.add(page);
  }

  hasVisited(page) {
    return this.visitedPages.has(page);
  }

  getVisitedPages() {
    return [...this.visitedPages];
  }

  getTotalUniqueVisits() {
    return this.visitedPages.size;
  }
}

const tracker = new UserVisitTracker();
tracker.recordVisit('/home');
tracker.recordVisit('/about');
tracker.recordVisit('/home'); // 重复访问不会重复记录

console.log(tracker.getVisitedPages()); // ['/home', '/about']
console.log(tracker.getTotalUniqueVisits()); // 2

3.4 标签管理系统

class TagManager {
  constructor() {
    this.tags = new Set();
  }

  addTag(tag) {
    this.tags.add(tag.toLowerCase());
  }

  removeTag(tag) {
    this.tags.delete(tag.toLowerCase());
  }

  hasTag(tag) {
    return this.tags.has(tag.toLowerCase());
  }

  getAllTags() {
    return [...this.tags];
  }
}

const tagManager = new TagManager();
tagManager.addTag('JavaScript');
tagManager.addTag('ES6');
tagManager.addTag('javascript'); // 不会重复添加

console.log(tagManager.getAllTags()); // ['javascript', 'es6']

4. WeakSet

WeakSet 是一种特殊的 Set,它只能存储对象引用,并且是弱引用。

4.1 基本用法

const ws = new WeakSet();
const obj1 = {};
const obj2 = {};

ws.add(obj1);
ws.add(obj2);

console.log(ws.has(obj1)); // true

ws.delete(obj1);
console.log(ws.has(obj1)); // false

4.2 实际应用场景

// 使用 WeakSet 跟踪 DOM 元素
const trackedElements = new WeakSet();

function track(element) {
  trackedElements.add(element);
}

function isTracked(element) {
  return trackedElements.has(element);
}

// 使用示例
const div = document.createElement('div');
track(div);
console.log(isTracked(div)); // true

5. 性能考虑

5.1 Set vs Array

// Set 的查找性能优于数组
const largeArray = Array.from({ length: 100000 }, (_, i) => i);
const largeSet = new Set(largeArray);

console.time('Array search');
largeArray.includes(99999);
console.timeEnd('Array search');

console.time('Set search');
largeSet.has(99999);
console.timeEnd('Set search');

5.2 内存优化

// 使用完后清空 Set
function processData(data) {
  const uniqueData = new Set(data);
  // 处理数据...
  uniqueData.clear(); // 及时清空释放内存
}

6. 最佳实践

  1. 使用 Set 处理唯一值集合
  2. 需要频繁查找操作时使用 Set 代替 Array
  3. 存储对象引用时考虑使用 WeakSet
  4. 合理使用 Set 的方法和属性
  5. 注意内存管理,及时清空不需要的 Set

网站公告

今日签到

点亮在社区的每一天
去签到