别误会,Map不只是地图

简介: 上集说到ES6中set方法,在ES6中除了增加set方法之外,还考虑到一种场景——`键值对的存储`,而`map`集合就是专门存储多个键值对(key value pair)的数据。

上集说到ES6中set方法,在ES6中除了增加set方法之外,还考虑到一种场景——键值对的存储,而map集合就是专门存储多个键值对(key value pair)的数据。

在map出现之前,我们使用的是对象的方式来存储键值对,键是属性名,值是属性值。键值对数据结合的特点就是:键不可重复。如果用对象来存储键值对在某些场景下不太如意:

  1. 键名只能是字符串或者符号,这就给它的使用带来很大的限制
  2. 获取数据的数量不方便,如果想知道对象中存了多少个数据,就必须先拿到所有的键名,然后通过求数组的长度才能知道对象中有多少个属性。
  3. 键名容易跟原型上的名称冲突。

0、如何创建map


 new Map();//创建一个没有任何内容的map集合

 new Map(iterable);//创建一个具有初始化内容的map,初始内容来自于可迭代对象每一次迭代的结果,但是,它要求每一次迭代的结果必须是一个长度为2的数组,数组第一项表示键,数组第二项表示值

例:创建一个没有任何内容的map集合

const mp = new Map();
console.log(mp);

执行结果:

例:创建一个有初始内容的map集合

const mp = new Map([["a",1],["b",2],["c",3]]);
console.log(mp);

执行结果:

1、如何进行后续操作

1、size:只读属性,获取当前map中键的数量

例:size

const mp = new Map([["a",1],["b",2],["c",3]]);
console.log(mp);
console.log("总数:",mp.size);

执行结果:

2、set(键,值):设置一个键值对,键和值可以是任何类型这也是跟Object存储的区别,对象只能是字符串

例:set()

const mp = new Map([["a",1],["b",2],["c",3]]);
mp.set("d",4)
console.log(mp);

执行结果:

注意点

  1. 如果键不存在,则添加一项
  2. 如果键存在,则修改它的值
  3. 判断键存不存在的方式与set相同,都为Object.is()

例:请问下面map中有几个值?

 const mp = new Map([["a",1],["b",2],["c",3]]);
       mp.set({},4);
       mp.set("a",abc);
       map.set({},00);
       console.log(mp);
       console.log("总数:",mp.size);

执行结果:

从结果看:有5个值,对象是引用值,它们的地址不同,所以不会覆盖,而a的原值1会被abc覆盖掉。如果说需要使用相同引用值对象,可以这样改:

const mp = new Map([["a",1],["b",2],["c",3]]);
       const obj = {};
       mp.set(obj,4);
       mp.set("a","abc");
       mp.set(obj,00);
       console.log(mp);
       console.log("总数:",mp.size);

执行结果:

3、get(键):根据一个键,得到一个值

例:get(键)

const mp = new Map([["a",1],["b",2],["c",3]]);
   
console.log("get('a')",mp.get("a"));

执行结果:

例:如果传入不存在的键

const mp = new Map([["a",1],["b",2],["c",3]]);
   
console.log("get('a')",mp.get("jasnbdjka"));

执行结果:

4、has(键):判断某个键是否存在

例:has()

 const mp = new Map([["a",1],["b",2],["c",3]]);
   
 console.log("has('a')",mp.has("a"));

执行结果:

5、delete(键):删除指定的键,成功返回true,失败返回false

例:delete(键)

const mp = new Map([["a",1],["b",2],["c",3]]);
   
console.log("delete('a')",mp.delete("a"));

执行结果:

6、clear():清空map

例:clear()

const mp = new Map([["a",1],["b",2],["c",3]]);
console.log(mp);

2、如何与数组进行转换

例:数组转换成map集合

//直接把数组放到 new Map(数组)就可以了
const mp = new Map(要转换的数组);
//如下:
const mp = new Map([["a",1],["b",2],["c",3]]);

例:map转换为数组

//map本身也是一个可迭代的对象,每次迭代的结果就是每一项的值
const mp = new Map([["a",1],["b",2],["c",3]]);
const arr = [...mp];
console.log(arr);

执行结果:

3、遍历

  1. 使用for of循环,每次迭代得到的是一个长度为2的数组

例:for of

   const mp = new Map([["a",1],["b",2],["c",3]]);
    
    for (const item of mp) {
        console.log(item);
    }

执行结果:

当然也可以直接解构

    const mp = new Map([["a",1],["b",2],["c",3]]);
    //方式一:
    for (const [key,value] of mp) {
        console.log(key,value);
    }
    //方式二:
    for (const item of mp) {
        console.log(item[0],item[1]);
    }

执行结果:

  1. 使用forEach遍历
  • 参数1:每一项的值
  • 参数2:每一项的键
  • 参数3:map本身

例:forEach

  const mp = new Map([["a",1],["b",2],["c",3]]);
        mp.forEach((value,key,that) =>{
            console.log(value,key,that);
        })

执行结果:

4、手写map

手写map方法跟浏览器提供的map方法是不一样的,因为我们没有办法调用底层代码,就当拓展思维了。

1、新建 myMap.js文件

class MyMap {
    constructor(iterable = []) {
        //验证是否是可迭代的对象
        this.isIterator(iterable);
        this._datas = [];
        for (const item of iterable) {
            //item 也得是一个可迭代对象
            this.isIterator(item);

            //取出第一个迭代值和第二个迭代值
            const iterator = item[Symbol.iterator]();
            const key = iterator.next().value;
            const value = iterator.next().value;
            this.set(key, value);
        }

    }
    //判断是否是可迭代对象
    isIterator(target) {
        if (typeof target[Symbol.iterator] !== "function") {
            throw new TypeError(`${typeof target} ${target} is not is not iterable (cannot read property Symbol(Symbol.iterator))`);
        }
    }

    //set方法
    set(key, value) {
        const obj = this._getObj(key);
        if (obj) {
            //如果存在键名,则修改值
            obj.value = value;
        } else {
            this._datas.push({
                key,
                value
            })
        }

    }
    //delete
    delete(key) {
        for (let i = 0; i < this._datas.length; i++) {
            const element = this._datas[i];
            if (this.isEqual(element.key, key)) {
                this._datas.splice(i, 1);
                return true;
            }
        }
        return false;
    }
    //get方法
    get(key) {
        const item = this._getObj(key);
        if (item) {

            return item.value;
        }
        return undefined;
    }

    //size方法
    get size() {
        return this._datas.length;
    }
    //has方法
    has(key) {
        return this._getObj(key) !== undefined; //不等于undefined,说明值找到了
    }
    //clear方法
    clear() {
        this._datas.length = 0;
    }
    //forEach
    forEach(callback) {
        for (const item of this._datas) {
            callback(item.value, item.key, this);
        }
    }

    /**
     * 根据key值从内部数组中,找到对应的数组项 
     * @param {*} key 
     */
    _getObj(key) {
        for (const item of this._datas) {
            if (this.isEqual(item.key, key)) {
                return item;
            }
        }
    }

    //使MyMap本身可迭代
    *[Symbol.iterator]() {
        for (const item of this._datas) {
            yield [item.key, item.value]
        }
    }


    /**
     * 判断两个数据是否相等
     * @param {*} data1 
     * @param {*} data2 
     */
    isEqual(data1, data2) {
        //如果data1和data2都等于0,那么我们认为它们相等
        if (data1 === 0 && data2 === 0) {
            return true;
        }
        return Object.is(data1, data2);
    }

代码测试:

<script src="./js/myMap.js"></script>
<script>
    const mp = new MyMap([["a",1],["b",2],["c",3]]);
    console.log(mp);
</script>

例:set方法

例:forEach

<script src="./js/yMap.js"></script>
<script>
    const mp = new MyMap([["a",1],["b",2],["c",3]]);
    mp.forEach((value,key,that) => {
        console.log(value,key,that);
    });

</script>

执行结果:

以上就是今天的分享了,希望可以帮到大家,我也是刚开始写技术文章,还有很多欠缺的地方,希望掘金大佬们多多指教,谢谢大家!!

相关文章
|
6月前
|
定位技术
97Echarts - 地理坐标/地图(Draw Polygon on Map)
97Echarts - 地理坐标/地图(Draw Polygon on Map)
25 0
|
6月前
|
定位技术
95Echarts - 地理坐标/地图(Binning on Map)
95Echarts - 地理坐标/地图(Binning on Map)
16 0
|
1天前
|
前端开发 定位技术 API
|
3月前
|
定位技术 Python
pyecharts从入门到精通-地图专题Map-带时间轴与网格的复杂绘图
pyecharts从入门到精通-地图专题Map-带时间轴与网格的复杂绘图
|
4月前
|
小程序 定位技术
uniapp 地图组件(map)的使用总结
uniapp 地图组件(map)的使用总结
138 0
|
9月前
|
开发框架 JavaScript 定位技术
Uniapp - 地图map组件及使用
Uniapp - 地图map组件及使用
781 0
|
9月前
|
小程序 JavaScript 定位技术
微信小程序-map地图
微信小程序-map地图
|
JavaScript 定位技术
echarts没有map地图解决方案
echarts没有map地图解决方案
180 0
echarts没有map地图解决方案
|
存储 索引
Map基础
MAP基础 map不同于普通的对象,普通对象的键值对,键只能是数值、字符串或者符号,而map的键可以是任意类型的值,包括对象、函数、数组等。
|
数据可视化 JavaScript 前端开发
地图可视化不只是pyecharts.map
导读:地图可视化是一种非常直观的数据分析结果展现形式,python有很多可视化库可以实现,pyecharts就是很多python爱好者喜爱的实现地图可视化方法之一。不可否认,pyecharts绘制的地图实现方便、图形美观而且支持交互,但在面对不同需求时,其实我们还有很多其他手段实现地图可视化。
296 0
地图可视化不只是pyecharts.map