Javascript数据结构——Map

作者: 梦安web开发 | 来源:发表于2020-11-02 00:26 被阅读0次

    JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。

    ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。

    1.常见的Map方法

    • 实例一个Map
    const m = new Map();
    
    • 添加成员元素 set
    m.set('name','galaxy')
    
    • 获取成员元素 get
    m.get('name','galaxy')
    
    • 查看成员元素是否存在has
    m.hsa('name')  //true
    
    • Map 结构的成员总数 size
    map.size
    
    • 删除某个键 delete
    m.delete('name')
    
    • 清除所有成员
    map.clear()
    

    2.遍历方法

    Map.prototype.keys():返回键名的遍历器。
    Map.prototype.values():返回键值的遍历器。
    Map.prototype.entries():返回所有成员的遍历器。
    Map.prototype.forEach():遍历 Map 的所有成员。

    • Map数据的遍历forEach
    items.forEach(
     ([key, value]) => map.set(key, value)
    );
    
    const map = new Map([
      ['F', 'no'],
      ['T',  'yes'],
    ]);
    
    for (let key of map.keys()) {
      console.log(key);
    }
    // "F"
    // "T"
    
    for (let value of map.values()) {
      console.log(value);
    }
    // "no"
    // "yes"
    
    for (let item of map.entries()) {
      console.log(item[0], item[1]);
    }
    // "F" "no"
    // "T" "yes"
    
    // 或者
    for (let [key, value] of map.entries()) {
      console.log(key, value);
    }
    // "F" "no"
    // "T" "yes"
    
    // 等同于使用map.entries()
    for (let [key, value] of map) {
      console.log(key, value);
    }
    // "F" "no"
    // "T" "yes"
    

    Map 结构转为数组结构,比较快速的方法是使用扩展运算符(...)

    const map = new Map([
      [1, 'one'],
      [2, 'two'],
      [3, 'three'],
    ]);
    
    [...map.keys()]
    // [1, 2, 3]
    
    [...map.values()]
    // ['one', 'two', 'three']
    
    [...map.entries()]
    // [[1,'one'], [2, 'two'], [3, 'three']]
    
    [...map]
    // [[1,'one'], [2, 'two'], [3, 'three']]
    

    结合数组的map方法、filter方法,可以实现 Map 的遍历和过滤(Map 本身没有map和filter方法)。

    const map0 = new Map()
      .set(1, 'a')
      .set(2, 'b')
      .set(3, 'c');
    
    const map1 = new Map(
      [...map0].filter(([k, v]) => k < 3)
    );
    // 产生 Map 结构 {1 => 'a', 2 => 'b'}
    
    const map2 = new Map(
      [...map0].map(([k, v]) => [k * 2, '_' + v])
        );
    // 产生 Map 结构 {2 => '_a', 4 => '_b', 6 => '_c'}
    

    3.数据结构的互相转换

    • Map 转为数组 使用扩展运算符(...)
      .set(true, 7)
      .set({foo: 3}, ['abc']);
    [...myMap]
    // [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
    
    • 数组 转为 Map
      将数组传入 Map 构造函数
    new Map([
      [true, 7],
      [{foo: 3}, ['abc']]
    ])
    // Map {
    //   true => 7,
    //   Object {foo: 3} => ['abc']
    // }
    
    • Map 转为对象
      如果所有 Map 的键都是字符串,它可以无损地转为对象。
    function strMapToObj(strMap) {
      let obj = Object.create(null);
      for (let [k,v] of strMap) {
        obj[k] = v;
      }
      return obj;
    }
    
    const myMap = new Map()
      .set('yes', true)
      .set('no', false);
    strMapToObj(myMap)
    // { yes: true, no: false }
    
    • Map 转为 JSON
      Map 转为 JSON 要区分两种情况。一种情况是,Map 的键名都是字符串,这时可以选择转为对象 JSON。
    function strMapToJson(strMap) {
      return JSON.stringify(strMapToObj(strMap));
    }
    
    let myMap = new Map().set('yes', true).set('no', false);
    strMapToJson(myMap)
    // '{"yes":true,"no":false}'
    
    • JSON 转为 Map
      JSON 转为 Map,正常情况下,所有键名都是字符串。
    function jsonToStrMap(jsonStr) {
      return objToStrMap(JSON.parse(jsonStr));
    }
    
    jsonToStrMap('{"yes": true, "no": false}')
    // Map {'yes' => true, 'no' => false}
    

    但是,有一种特殊情况,整个 JSON 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组。这时,它可以一一对应地转为 Map。这往往是 Map 转为数组 JSON 的逆操作。

    function jsonToMap(jsonStr) {
      return new Map(JSON.parse(jsonStr));
    }
    
    jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
    // Map {true => 7, Object {foo: 3} => ['abc']}
    

    相关文章

      网友评论

        本文标题:Javascript数据结构——Map

        本文链接:https://www.haomeiwen.com/subject/ideypktx.html