记录于 05月21日 · 木曜日5 min read
Set 和 Map 数据结构
ES6 新提供了数据结构 Set 与 Map,使用这个两个数据进行开发,会起到简洁代码逻辑更清晰的效果。
结论:Set 类似一个数组,但内容唯一,Map 则解决了键值对,必须由字符串对应值,变成了值对值,并且只要内存中地址不同就会被视为新的键值。
const s = new Set();
[2, 3, 4, 5, 6, 2, 2].forEach(x => s.add(x));
console.log(...s);
//2,3,4,5,6
JavaScript
上述代码通过 add() 方法向 Set 结构加入成员,结果表明 Set 结构不会添加重复的值。
Set函数可以接受一个数组(或者具有 iterable(可迭代的意思)接口的其他数据结构)偶为参数,用来初始化。
//例一
const set = new Set([1,2,3,4,4])
[...set]
//[1,2,3,4]
//例二
const items = new Set([1,2,3,4,5,5,5,5,5])
items.size // 5
//例三
const set = new Set(document.querySelectorAll('div'))
set.size // 56
//类似于
const set = new Set();
document
.querySelectorAll('div')
.forEach(div => set.add(div));
set.size // 56
JavaScript
上述代码中,例一和例二都是 Set 函数接受数组作为参数,例三是接受蕾丝数组的对象作为参数。
上面代码也展示了一种去除数组重复成员的方法。
//去除数组的重复成员
[...new Set(array)];
JavaScript
上面的方法也可以用于,去除字符里面的重复字符。👇
[...new Set('ababbc')].join('');
// "abc"
JavaScript
注意:向 Set 中加入值不会被类型转换,所以"5"与 5 是不同的值。内部会进进行类似===的精确判断,所以 Size 会是 2.
另外,两个对象总是不想等的。所以添加对象会没有限制。
Array.from 方法可以将 Set 结构转为数组。
const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);
JavaScript
这就提供了去除数组重复成员的另一种方法。
function dedupe(array) {
return Array.from(new Set(array));
}
dedupe([1, 1, 2, 3]); // [1, 2, 3]
JavaScript
Map
Map 解决 es6 之前的一大问题就是,object 对象,本质上是键值对的集合,但只能使用字符串当作键。
ES6 提供了 Map 数据结构。它类似于对象,也是键值对集合,但键的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
const map = new Map();
map.set(['a'], 555);
map.get(['a']); // undefined
JavaScript
上面的代码,表面上是针对同一个键,但实际上是两个不同的数组实例,内存地址是不同的,所以 get 方法无法获取到该键,返回 undefined
注意:由上可知,Map 的键实际上是跟内存地址绑定的,只要内存地址不同,就会视为两个键。这就解决了同名属性碰撞的问题,扩展别人的时候,就不用担心自己的属性与别人相同了。
如果Map 的键是一个简单类型的值(number,String,boolean),则只要两个值严格相等,Map 将会视其为一个键,比如 0 与-0 就送一个,true 与字符串“true”就是不同的。
let map = new Map();
map.set(-0, 123);
map.get(+0); // 123
map.set(true, 1);
map.set('true', 2);
map.get(true); // 1
map.set(undefined, 3);
map.set(null, 4);
map.get(undefined); // 3
map.set(NaN, 123);
map.get(NaN); // 123
JavaScript