Skip to content

一文搞懂 Map、Set

1.Array <-> Set

数组去重

js
const mySet = new Set(myArray); // 创建一个包含唯一元素的 Set
const myArray = Array.from(mySet); // 将 Set 转换为 Array
//或者 const myArray = [...mySet];

…扩展运算符和 Array.from()哪个更好用,它们分别可以把哪些类型变成数组?

两者都可以转化的:数组、Set、Map、类数组对象(对象不可以,因为对象是不可迭代的)

扩展运算符专门可以的:字符串(也是可迭代对象)

对象也有专门的对象扩展运算符:ES9 提出

js
const defaults = { a: 0, b: 1 };
const options = { b: 2, c: 3 };
const merged = { ...defaults, ...options };

2.Array <-> Map

二维数组可以直接互相转换:和对象差不多一个道理(对象是通过 entries 方法)

你可以将数组和 Map 之间进行相互转换,尽管它们是不同的数据结构,但在一些情况下可以相互转换以满足不同的需求。

从数组到 Map 的转换

你可以通过遍历数组并将数组元素作为键值对添加到 Map 中,实现从数组到 Map 的转换。

js
const array = [
  ["a", 1],
  ["b", 2],
  ["c", 3],
];
const map = new Map(array);
console.log(map); // 输出:Map { 'a' => 1, 'b' => 2, 'c' => 3 }

从 Map 到数组的转换

你可以使用 Array.from() 方法将 Map 转换为一个包含键值对数组的数组。

js
const map = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3],
]);
const array = Array.from(map);
console.log(array); // 输出:[ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]

需要注意的是,转换为数组时,Map 的键值对会以数组形式存储在数组中。

虽然数组和 Map 之间可以相互转换,但是它们的用途和特性不同,根据你的实际需求来选择合适的数据结构。如果需要有序的键值对,并且需要使用各种类型的键(而不仅限于字符串或符号),那么使用 Map 是更合适的选择。如果只需要简单的索引关系,数组可能更适合。

一维数组怎么办?

没办法直接转化,只能遍历数组,然后给 Map 设置键值对!

一维数组可以转化为 Map,但需要注意,数组的结构不同于键值对的形式,所以在转换时需要考虑如何设置键和值。在转换为 Map 时,你需要为每个数组元素指定一个键和一个值。一种常见的做法是将数组索引作为键,数组元素作为值。以下是如何将一维数组转换为 Map 的示例:

js
const array = [1, 2, 3, 4];
const map = new Map();

for (let i = 0; i < array.length; i++) {
  map.set(i, array[i]);
}

console.log(map);
// 输出:
// Map { 0 => 1, 1 => 2, 2 => 3, 3 => 4 }

在上面的示例中,我们使用循环遍历数组的每个元素,并将索引作为键,数组元素作为值,然后将它们添加到 Map 中。这样就创建了一个以数组索引为键的 Map

3.Set 的介绍和遍历

基本介绍

Set 是 JavaScript 中的一种集合数据结构,它允许你存储一组唯一的值,而且这些值是无序的。每个值只能在 Set 中出现一次,因此 Set 可以用于确保集合中的元素不重复。Set 在处理数据时非常有用,特别是需要维护一组不同值的场景。

Set 中的元素是无序的,虽然保留了插入顺序。

遍历

在 JavaScript 中,你可以使用不同的方式来遍历 Set 集合的元素。以下是一些常用的遍历方式:

  1. 使用 for...of 循环: 使用 for...of 循环是遍历 Set 最常见的方式。

注意:for...of 循环不会遍历原型链上的属性或方法。它只会遍历对象自身的可迭代属性。

要和 for…in 进行区别!!

js
const mySet = new Set([1, 2, 3, 4]);

for (const item of mySet) {
  console.log(item);
}
// 输出:
// 1
// 2
// 3
// 4
  1. 使用 forEach 方法: Set 对象具有 forEach 方法,可以用于遍历元素。
js
const mySet = new Set([1, 2, 3, 4]);

mySet.forEach((item) => {
  console.log(item);
});
// 输出:
// 1
// 2
// 3
// 4
  1. Set 转换为数组后遍历: 你可以将 Set 转换为数组,然后使用数组的遍历方法。
js
const mySet = new Set([1, 2, 3, 4]);
const myArray = Array.from(mySet);

for (const item of myArray) {
  console.log(item);
}
// 输出:
// 1
// 2
// 3
// 4

需要注意的是,虽然 Set 是无序的,但是Set 集合保留了插入顺序,所以在遍历时会按照元素插入的顺序进行迭代。遍历 Set 集合时,不会出现重复的元素,因为 Set 保证了元素的唯一性。

4.Map 的介绍,获取键和值以及遍历

基本介绍

Map 是 JavaScript 中的一种键值对数据结构,它允许你存储任意类型的键和对应的值,而且这些键值对是无序的。Map 在处理键值关系时非常有用,特别是需要维护复杂数据映射的场景。

Map 中的键值对是无序的,虽然保留了插入顺序。

怎么得到 Map 对象的所有 key 或者 value 呢?

要获取 Map 对象的所有键(keys)或所有值(values),你可以使用 Map 对象的内置方法和迭代器。以下是如何做的示例:

1.获取所有键(keys)并遍历

  1. 使用 keys() 方法和 for...of 循环:(使用 forEach 也可以)
js
const map = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3],
]);

const keys = map.keys();
for (const key of keys) {
  //可以直接像遍历数组一样遍历
  console.log(key);
}
// 输出:
// a
// b
// c
  1. keys() 方法的结果转换为数组:
js
const map = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3],
]);

const keysArray = Array.from(map.keys());
console.log(keysArray); // 输出:[ 'a', 'b', 'c' ]

2.获取所有值(values)

  1. 使用 values() 方法和 for...of 循环:
js
const map = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3],
]);

const values = map.values();
for (const value of values) {
  console.log(value);
}
// 输出:
// 1
// 2
// 3
  1. values() 方法的结果转换为数组:
js
const map = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3],
]);

const valuesArray = Array.from(map.values());
console.log(valuesArray); // 输出:[ 1, 2, 3 ]

需要注意的是,keys() 方法和 values() 方法返回的都是可迭代对象,你可以使用 for...of 循环或转换为数组来获取键或值。如果你需要同时获取键和值,可以使用 entries() 方法,并对其使用相同的方法。

注意:map.keys()和 values()方法不同于 object 的 Object.keys(obj)和 Object.values(obj)方法,不要搞混淆了

特别注意:map.keys()和 values()方法都不是直接返回的数组,而是返回的可迭代对象

具体是啥样的可迭代对象呢?

是一种 Map 特有的:

image-20230820045438841