ES6以前,JavaScript通过Object的方式实现“键/值”式的存储(Hash结构),也就是使用对象属性作为键再通过属性来引用值。
ES6新增了一种Map集合类型的新特性,基于此特性,JavaScript有了正真的“键/值”存储机制。
- 使用new关键字和Map构造函数创建一个空映射
- 通过给Map构造函数传入一个可迭代对象,在创建的同时初始化实例
// 创建空映射
const map_1 = new Map();
// 创建并初始化实例
const map_2 = new Map([
["key_1", "value_1"],
["key_2", "value_2"],
["key_3", "value_3"]
]);
Map实例的属性与操作方法
- size:获取映射中键值对的数量
- set(key, value):添加新的键/值对
- get(key):读取键对应的值
- has(key):判断是否有某个键
- get(key):读取键对应的值
- delete(key):删除某个键
- clear():清空
浅浅尝试一下(示例如下:)
const m = new Map();
m.set("firstName", "Matt")
.set("secondName", "KD")
.set("lastName", "Frisbie");
console.log(m.size); // 3
console.log(m.has("firstName")); // true
console.log(m.get("firstName")); // Matt
m.delete("firstName");
console.log(m.size); // 2
console.log(m.has("firstName")); // false
console.log(m.get("firstName")); // undefined
m.clear();
console.log(m.size); // 0
Map实例的遍历方法
- keys():返回以插入顺序生成的键迭代器
- values():返回以插入顺序生成的值迭代器
- entries():返回以插入顺序生成的键/值对迭代器
- forEach():迭代Map的所有成员
浅浅尝试一下(示例如下:)
const m = new Map().set("firstName", "Matt")
.set("secondName", "KD")
.set("lastName", "Frisbie");
console.log(m.keys());
console.log(m.values());
console.log(m.entries());
m.forEach((value, key) => console.log(`${key} -> ${value}`));
运行结果:
与Object只能使用数值、字符串、或者符号作为键不同,Map可以使用任何JavaScript数据类型作为键。此外,与Object类似,映射的值是没有限制的。因此:Map是一种更完善的Hash结构实现。
(示例如下:)
const m = new Map();
const functionKey = function() {};
const symbolKey = Symbol();
const objectKey = new Object();
m.set(functionKey, "functionValue")
.set(symbolKey, "symbolValue")
.set(objectKey, "objectValue");
console.log(m.get(functionKey)); // functionValue
console.log(m.get(symbolKey)); // symbolValue
console.log(m.get(objectKey)); // objectValue
基于以上对Map集合类型的认识,本例通过Map实现数组去重。
思路:遍历原始数组,将数组中的每一个元素作为Key存到Map中,因为Map集合中不会出现相同的Key值,因此最终得到的Map中所有的Key值就是去重后的结果
代码实现:
let repeatArr = [];
function nonRepeat(arr) {
let hashMap = new Map();
let result = [];
for(let i = 0; i < arr.length; i++) { // 遍历原始数组
if(hashMap.has(arr[i])) { // 判断是否存在该Key值
repeatArr.push(arr[i]);
} else {
hashMap.set(arr[i], "noRepeat");
}
}
for(let key of hashMap.keys()) { // for-of遍历键迭代器
result.push(key)
}
return result;
}
let array = [1,1,2,3,3,4];
console.log(nonRepeat(array)); // 打印去重结果
console.log(repeatArr); // 打印重复元素
以上是我写的第一个版本,摒弃了简洁明了的for-of遍历键迭代器,于是稍作修改,通过forEach(callback, thisArg),仅通过声明回调函数遍历键迭代器,将遍历的Key值依次通过栈方法push()推入去重结果数组
代码实现:
let repeatArr = [];
function nonRepeat(arr) {
let hashMap = new Map();
let result = [];
for(let i = 0; i < arr.length; i++) {
if(hashMap.has(arr[i])) {
repeatArr.push(arr[i]);
} else {
hashMap.set(arr[i], "noRepeat");
}
}
hashMap.forEach((value, key) => result.push(key));
return result;
}
let array = [1,1,2,3,3,4];
console.log(nonRepeat(array)); // [1,2,3,4]
console.log(repeatArr); // [1,3]
去重方法千千万,本章通过简明扼要地阐述ES6新增集合数据类型Map的介绍与使用,同时以数组去重的小案例加深巩固了对Map数据类型的理解,基于我写的代码只是简单的去重可能不够完善,有小伙伴有更完善的方案评论区留言鸭!