Map 和 Set 是 JavaScript 中两种常用的数据结构,它们都是 ES6 引入的 ,相比于普通的对象(Object)和数组(Array),Map 和 Set 提供了更多的灵活性和功能。
1. Map 和 Set 的定义
-
Map:是一种键值对(key-value)的集合,类似于对象(Object),但是它的键(key)可以是任何类型的值,而不仅仅是字符串或符号。特点:
- 键值对数据结构。
- 键(key)可以是任何类型(对象、数组、函数等)。
- 保证元素按插入顺序排序。
- 可以使用
.set(key, value)设置键值对,使用.get(key)获取值。
-
Set:是一个集合(set),其中每个元素都是唯一的。可以存储任何类型的值,但不允许重复的元素。特点:
- 值的集合(没有重复的值)。
- 存储唯一值。
- 保证元素按插入顺序排序。
- 可以使用
.add(value)添加元素,使用.has(value)检查是否包含元素。
2. Map 和 Set 的区别
| 特性 | Map |
Set |
|---|---|---|
| 结构 | 键值对(key-value pairs) | 唯一的值(unique values) |
| 键的类型 | 键可以是任意数据类型(例如:对象、数组、函数等) | 只能存储唯一的值,值可以是任何类型 |
| 重复值 | 可以存储相同的值,但必须有不同的键 | 不允许存储重复的值 |
| 迭代顺序 | 按照插入顺序迭代元素 | 按照插入顺序迭代元素 |
| 存储方式 | 键值对,映射键到值 | 存储单个唯一的值 |
| 常用方法 | .set(key, value), .get(key), .has(key), .delete(key), .clear() |
.add(value), .has(value), .delete(value), .clear() |
| 键的唯一性 | 键必须唯一 | 值必须唯一 |
3. 实际应用场景
Map 的应用场景:
-
存储键值对 :如果需要将数据存储为一对一的关系,可以使用
Map。- 示例:存储用户的 ID 和信息,或存储产品的 ID 和价格等。
cconst map = new Map(); map.set(1, 'apple'); map.set('name', 'John'); console.log(map.get(1)); // 'apple' console.log(map.get('name')); // 'John' -
需要任意类型作为键 :当需要将对象、数组、函数等作为键时,
Map比对象更有优势。arduinoconst objKey = { id: 1 }; const map = new Map(); map.set(objKey, 'User Info'); console.log(map.get(objKey)); // 'User Info' -
维护插入顺序 :
Map保证键值对按插入顺序排序,适合需要按照插入顺序遍历的场景。cconst map = new Map(); map.set(2, 'two'); map.set(1, 'one'); map.set(3, 'three'); for (let [key, value] of map) { console.log(key, value); } // 输出: // 2 'two' // 1 'one' // 3 'three'
Set 的应用场景:
-
存储唯一值 :如果需要存储没有重复的值,可以使用
Set。- 示例:去重数组中的元素。
vbscriptconst set = new Set([1, 2, 2, 3, 4, 4]); console.log(set); // Set { 1, 2, 3, 4 } -
检查元素是否存在 :
Set提供了.has(value)方法,可以高效地检查某个元素是否已经存在。vbscriptconst set = new Set([1, 2, 3]); console.log(set.has(2)); // true console.log(set.has(4)); // false -
集合运算 :
Set可以非常方便地做集合运算,例如交集、并集、差集等。通过Set和Map可以轻松实现一些数学集合操作。javascript// 并集 const setA = new Set([1, 2, 3]); const setB = new Set([3, 4, 5]); const union = new Set([...setA, ...setB]); console.log(union); // Set { 1, 2, 3, 4, 5 } -
快速查找 :由于
Set内部是基于哈希表实现的,因此它的查找效率高于普通的数组,尤其是在需要频繁查找某个值时。vbscriptconst set = new Set([1, 2, 3, 4, 5]); console.log(set.has(3)); // true
4. 性能对比
-
Map和Set都是基于哈希表实现的,插入、删除、查找的时间复杂度均为 O(1) ,因此在大多数情况下,它们的性能优于基于数组的操作(如.indexOf())。arduinoconst arr = [1, 2, 3, 4, 5]; console.log(arr.indexOf(3)); // O(n) const set = new Set([1, 2, 3, 4, 5]); console.log(set.has(3)); // O(1)
总结:
| 特性 | Map |
Set |
|---|---|---|
| 存储类型 | 键值对(key-value) | 唯一的值(unique values) |
| 键的类型 | 键可以是任何数据类型(对象、函数、数组等) | 存储的值可以是任何类型 |
| 重复性 | 键必须唯一,值可以重复 | 不允许值重复 |
| 常见用途 | 需要维护键值对数据(例如 ID 和信息的映射) | 需要保证唯一性的集合(如去重、快速查找) |
Map更适合用于需要键值对的场景(例如存储用户信息、配置项、缓存数据等),并且需要键为任意类型时。Set更适合用于存储唯一的值,尤其是去重、集合运算和高效查找的场景。