Set和Map数据结构怎么用?

ES6引入的SetMap是两种关键的数据结构,它们为JavaScript带来了真正意义上的集合和映射能力,弥补了传统对象和数组在某些场景下的不足。理解并运用它们能显著提升特定算法的效率和代码的表达力。

Set:值唯一的集合

Set对象允许你存储任何类型的唯一值。它的核心特性是自动确保内部的元素不重复,这对于数组去重、记录已访问节点等任务来说是天作之合。

const uniqueNumbers = new Set([1, 2, 2, 3, 3]);
console.log([...uniqueNumbers]); // [1, 2, 3]

const tags = new Set();
tags.add('JavaScript');
tags.add('CSS');
tags.add('JavaScript'); // 重复,添加无效
console.log(tags.has('CSS')); // true
tags.delete('CSS');
console.log(tags.size); // 1

你可以通过add添加元素,has检查存在,delete删除元素,size获取数量。Set的迭代顺序就是元素插入的顺序。它的值唯一性是基于“SameValueZero”算法,这意味着NaN也被视为等于自身,而对象则通过引用判断。

Map:键值对的集合

Map对象用于存储键值对集合。与普通对象最大的不同在于,Map的键可以是任意类型(对象、函数、基本类型都可以),而不仅限于字符串或Symbol。

const map = new Map();
const objKey = { id: 1 };
map.set(objKey, 'value for object');
map.set(123, 'value for number');
map.set('name', 'Alice');

console.log(map.get(objKey)); // 'value for object'
console.log(map.has(123)); // true
console.log(map.size); // 3

for (let [key, value] of map) {
  console.log(key, value);
}

Map通过setgethasdelete等方法进行操作。它同样维护键值对的插入顺序,这在需要有序迭代时非常有用。

与Object和Array的对比

使用Map而非普通对象的主要场景包括:

  • 当键的类型未知或动态,且可能为非字符串时。
  • 需要严格的元素插入顺序(虽然现代对象也保留了属性顺序,但Map的语义更明确)。
  • 频繁地添加和删除键值对(Map在性能上通常更优)。

使用Set而非数组的主要场景包括:

  • 需要自动保证元素的唯一性。
  • 需要高效地检查某个值是否存在(Sethas方法是O(1)的时间复杂度,而数组的includesindexOf是O(n))。

WeakSetWeakMap是它们的变体,只接受对象作为键(对于WeakMap)或值(对于WeakSet),并且持有的是对象的“弱引用”。这意味着,如果该对象在其他地方没有被引用,它会被垃圾回收,即使它存在于WeakMap/WeakSet中。这非常适合用于存储对象的私有数据或关联元数据,而无需担心内存泄漏。

在现代JavaScript中,Set常用于去重和集合运算(如交集、并集)。Map则非常适合用作缓存、建立对象间的关系映射,或存储需要复杂键的数据字典。它们都是现代算法和数据处理中不可或缺的工具。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发

    暂无评论内容