在 JavaScript 中Set()/Map()的完整指南
ES6中,如果希望数组的元素 不会重复,可以使用 Set; 如果希望对象的键不会重复,可以使用 Map
Set
Set 的特色是有 has() 这个方法,可以快速判断 Set 中是否包含某个元素, 虽然数组的 includes() 方法也可以实现这个。
以下是 Set 的 增、删 、有无、 遍历 的方法, 可以想一下 Array 对应的方法
const obj = {
foo: 'bar',
};
const mySet = new Set();
mySet.add(1); // [1]
mySet.add(5); // [1, 5]
mySet.add(5); // [1, 5],重复的元素不会被加进去
mySet.add(obj); // [ 1, 5, { foo: 'bar' } ]
mySet.has(5); // true
mySet.has(obj); // true
mySet.has({
foo: 'bar',
}); // false
mySet.delete(5); // true,刪除成功
mySet.delete(2); // false,刪除失败
mySet.size; // 2
//遍历
mySet.forEach((item) => console.log('item', item)); //item 1 item 5 item {foo: 'bar'}
//清空
mySet.clear();
Set集合与数组的转换
// Set 转 Array
let mySetArray = [...mySet];
// Array 转 Set
let mySet = new Set([]);
去除数组中重复的值
利用Set 中元素不会重复的特性
const arr = [1, 1, 3, 5, 5, 7];
const mySet = new Set(arr); // Set { 1, 3, 5, 7 }
const uniqueArray = [...mySet]; // [ 1, 3, 5, 7 ]
Map
- Map 里面的key 是唯一的,重复添加,则旧的value 会被覆盖。
- Map中的 keys 会根据被添加资料的时间而有顺序性,但 Object 没有顺序性。
- Object 的键(key)只能是 字串 或
Symbols,而 Map 的键可以是任何值,包含对象、函数或原始型别(primitive type)。 - 若要取得 Map 的大小只需要取得size 属性即可;而Object 的大小必须手动决定
语法
let keyString = 'a string',
keyObj = {},
keyFunc = function () {};
// .set(key, value) 來在 Map 中添加属性
myMap.set(keyString, 'value associated with string');
myMap.set(keyObj, 'value associated with object');
myMap.set(keyFunc, 'value associated with function');
// 方法
myMap.has(keyString); // true
myMap.size; // 3 .size 來取得 Map 內属性数目
myMap.get(keyString); // 使用 .get(key) 取属性的內容
myMap.delete(keyString); // 刪除 Map 中的某个属性,成功刪除返回 true,否则 false
myMap.clear(); // 清空整个 Map
与数组对象的关系
const kvArray = [
["key1", "value1"],
["key2", "value2"],
];
// 使用常规的 Map 构造函数可以将一个二维的键值对数组转换成一个 Map 对象
const myMap = new Map(kvArray);
console.log(myMap.get("key1")); // "value1"
// 使用 Array.from 函数可以将一个 Map 对象转换成一个二维的键值对数组
console.log(Array.from(myMap)); // 输出和 kvArray 相同的数组
// 更简洁的方法来做如上同样的事情,使用展开运算符
console.log([...myMap]);
// 或者在键或者值的迭代器上使用 Array.from,进而得到只含有键或者值的数组
console.log(Array.from(myMap.keys())); // 输出 ["key1", "key2"]
复制或合并 Maps
const original = new Map([[1, "one"]]);
const clone = new Map(original);
console.log(clone.get(1)); // one
console.log(original === clone); // false. 浅比较 不为同一个对象的引用
Map 对象间可以进行合并,但是会保持键的唯一性。
const first = new Map([
[1, "one"],
[2, "two"],
[3, "three"],
]);
const second = new Map([
[1, "uno"],
[2, "dos"],
]);
// 合并两个 Map 对象时,如果有重复的键值,则后面的会覆盖前面的。
// 展开语法本质上是将 Map 对象转换成数组。
const merged = new Map([...first, ...second]);
console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
Map 对象也能与数组合并:
const first = new Map([
[1, "one"],
[2, "two"],
[3, "three"],
]);
const second = new Map([
[1, "uno"],
[2, "dos"],
]);
// Map 对象同数组进行合并时,如果有重复的键值,则后面的会覆盖前面的。
const merged = new Map([...first, ...second, [1, "eins"]]);
console.log(merged.get(1)); // eins
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three