数组去重-Map实现

文章目录  

一、Map简介

ES6以前,JavaScript通过Object的方式实现“键/值”式的存储(Hash结构),也就是使用对象属性作为键再通过属性来引用值。

ES6新增了一种Map集合类型的新特性,基于此特性,JavaScript有了正真的“键/值”存储机制。

基本API

  1. 使用new关键字和Map构造函数创建一个空映射
  2. 通过给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}`));

运行结果:

 更完善的Hash结构

与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数据类型的理解,基于我写的代码只是简单的去重可能不够完善,有小伙伴有更完善的方案评论区留言鸭!