1. <output id="hzk7v"><pre id="hzk7v"><address id="hzk7v"></address></pre></output>
      <output id="hzk7v"></output>
    2. <nav id="hzk7v"><i id="hzk7v"><em id="hzk7v"></em></i></nav>
    3. <listing id="hzk7v"><delect id="hzk7v"><em id="hzk7v"></em></delect></listing>

      ES6中Set和Map数据结构£¬Map与其它数据结构互相转换操作实例详解

       更新时间£º2019年02月28日 10:31:10   作者£º沉静地闪光   我要评论

      这篇文章主要介绍了ES6中Set和Map数据结构£¬Map与其它数据结构互相转换操作,结合实例形式详细分析了ES6中的Set和Map数据结构的概念¡¢原理¡¢遍历¡¢去重等操作,以及Map与其它数据结构互相转换操作,需要的朋友可以参考下

      本文实例讲述了ES6中Set和Map数据结构£¬Map与其它数据结构互相转换操作¡£分享给大家供大家参考£¬具体如下£º

      ES6 的 Set:

      ES6 提供了新的数据结构©¤©¤Set¡£它类似于数组£¬但是成员的值都是唯一的£¬没有重复的值¡£

      Set 本身是一个构造函数£¬用来生成 Set 数据结构¡£

      Array和Set?#21592;?/strong>

      都是一个存储多值的容器£¬两者可以互相转换£¬但是在使用场景上有区别¡£如下:

      ¢ÙArray的indexOf方法比Set的has方法效?#23454;?#19979;
      ¢ÚSet不含有重复值£¨可以利用这个特性实现对一个数组的去重£©
      ¢ÛSet通过delete方法删除某个值£¬而Array只能通过splice¡£两者的使用方便程度前者更优
      ¢ÜArray的很多新方法map¡¢filter¡¢some¡¢every等是Set没有的£¨但是通过两者可以互相转换?#35789;?#29992;£©

      一¡¢Set 实例的操作方法£º

      let set = new Set();
      set.add(1);
      set.add("1");
      console.log(set.size); // 2
      
      

      可以使用数组来初始化一个 Set £¬并且 Set 构造器会确保不重复地使用这些值:

      let set = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
      console.log(set.size); // 5
      
      

      add(value): 添加某个值£¬返回Set结构本身
      has(value): 返回?#32423;?#20540;£¬表示该值是否为Set的成员

      let set = new Set();
      set.add(1);
      set.add("1");
      console.log(set.has(1)); // true
      console.log(set.has(6)); // false
      
      

      delete(value): 删除某个值£¬返回一个?#32423;?#20540;£¬表示是否成功
      clear(value):清除所有成员£¬没有返回值

      let set = new Set();
      set.add(1);
      set.add("1");
      console.log(set.has(1)); // true
      set.delete(1);
      console.log(set.has(5)); // false
      console.log(set.size); // 1
      set.clear();
      console.log(set.size); // 0
      
      

      二¡¢Set遍历操作

      keys():返回键名的遍历器
      values(): 返回健值对的遍历器
      entries():返回键值对的遍历器
      forEach(): 每个成员

      let set = new Set(['red', 'green', 'blue']);
      for (let item of set.keys()) {
       console.log(item);
      }
      // red
      // green
      // blue
      for (let item of set.values()) {
       console.log(item);
      }
      // red
      // green
      // blue
      for (let item of set.entries()) {
       console.log(item);
      }
      // ["red", "red"]
      // ["green", "green"]
      // ["blue", "blue"]
      
      

      forEach()

      let set = new Set([1, 2]);
      set.forEach(function(value, key, ownerSet) {
        console.log(key + "£º " + value);
      });
      // 输出
      // 1 £º1
      // 2£º 2
      
      

      三¡¢ES6数组去重£¨面试也经常会?#23454;?#25968;组去重的问题£©

      let arr = [1, 2, 2, 3];
      let set = new Set(arr);
      let newArr = Array.from(set);
      console.log(newArr); // [1, 2, 3]
      
      

      Set集合转化Array数组

      let set = new Set([1, 2, 3, 3, 4]);
      let arr = Array.from(set) //输出[1,2,3,4]
      
      

      四¡¢WeakSet

      WeakSet结构与Set类似£¬它与Set有两个区别£º

      ¢ÙweakSet的成员只能是对象£¬不能是其他类型的值£»
      ¢ÚweakSet对象都是弱引用¡£如果其它对象不再引用该对象£¬那么垃圾回收机制会自动回收该对象所占的内存£¬所以WeakSet是不可遍历的¡£

      WeakSet 结构有以下三个方法£º

      WeakSet.prototype.add(value)?#21512;?WeakSet 实例添加一个新成员¡£
      WeakSet.prototype.delete(value)£º清除 WeakSet 实例的指定成员¡£
      WeakSet.prototype.has(value)£º返回一个?#32423;?#20540;£¬表示某个值是否在 WeakSet 实例之中¡£

      WeakSet的一个用处是储存DOM节点£¬而不用担心这些节点会从文档中移除时£¬会引发内存泄露¡£

      ES6的Map:

      一¡¢ES6 的 Map含义和基本用法

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

      ES6 提供了 Map 数据结构¡£它类似于对象£¬也是键值对的集合£¬但是¡°键¡±的范围不限于字符串£¬各种类型的值£¨包括对象£©都可以当作键¡£也就是?#25285;¬Object 结构提供了¡°字符串¡ª值¡±的对应£¬Map 结构提供了¡°值¡ª值¡±的对应£¬是一种更完善的 Hash 结构实现¡£

      const m = new Map();
      const o = {p: 'Hello World'};
      m.set(o, 'content')
      m.get(o) // "content"
      m.has(o) // true
      m.delete(o) // true
      m.has(o) // false
      
      

      上面代码使用 Map 结构的set方法£¬将对象o当作m的一个键£¬然后?#36136;?#29992;get方法读取这个键£¬接着使用delete方法删除了这个键¡£

      实例的属性和操作方法 ¡ì ⇧

      二¡¢Map 结构的实例有以下属性和操作方法£º

      1.size 属性

      size属性返回 Map 结构的成员总数¡£

      const map = new Map();
      map.set('foo', true);
      map.set('bar', false);
      map.size // 2
      
      

      2.set(key, value)

      set方法设置键名key对应的键值为value£¬然后返回整个 Map 结构¡£如果key已经有值£¬则键值会被更新£¬否则就新生成该键¡£

      const m = new Map();
      m.set('edition', 6)    // 键是字符串
      m.set(262, 'standard')   // 键是数值
      m.set(undefined, 'nah')  // 键是 undefined
      
      

      set方法返回的是当前的Map对象£¬因此可以采用链式写法¡£

      let map = new Map()
       .set(1, 'a')
       .set(2, 'b')
       .set(3, 'c');
      
      

      3.get(key)

      get方法读取key对应的键值£¬如果找不到key£¬返回undefined¡£

      const m = new Map();
      const hello = function() {console.log('hello');};
      m.set(hello, 'Hello ES6!') // 键是函数
      m.get(hello) // Hello ES6!
      
      

      4.has(key)

      has方法返回一个?#32423;?#20540;£¬表示某个键是否在当前 Map 对象之中¡£

      const m = new Map();
      m.set('edition', 6);
      m.set(262, 'standard');
      m.set(undefined, 'nah');
      m.has('edition')   // true
      m.has('years')    // false
      m.has(262)      // true
      m.has(undefined)   // true
      
      

      5.delete(key)

      delete方法删除某个键£¬返回true¡£如果删除失败£¬返回false¡£

      const m = new Map();
      m.set(undefined, 'nah');
      m.has(undefined)   // true
      m.delete(undefined)
      m.has(undefined)    // false
      
      

      6.clear()

      clear方法清除所有成员£¬没有返回值¡£

      let map = new Map();
      map.set('foo', true);
      map.set('bar', false);
      map.size // 2
      map.clear()
      map.size // 0
      
      

      三¡¢Map遍历方法

      Map 结构原生提供三个遍历器生成函数和一个遍历方法£º

      keys()£º返回键名的遍历器¡£
      values()£º返回键值的遍历器¡£
      entries()£º返回所有成员的遍历器¡£
      forEach()£º遍历 Map 的所有成员¡£

      需要特别注意的是£¬Map 的遍历顺序就是插入顺序¡£

      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"
      
      

      四¡¢WeakMap

      WeakMap结构与Map结构类似£¬也是用于生成键值对的集合¡£

      // WeakMap 可以使用 set 方法添加成员
      const wm1 = new WeakMap();
      const key = {foo: 1};
      wm1.set(key, 2);
      wm1.get(key) // 2
      // WeakMap 也可以接受一个数组£¬
      // 作为构造函数的参数
      const k1 = [1, 2, 3];
      const k2 = [4, 5, 6];
      const wm2 = new WeakMap([[k1, 'foo'], [k2, 'bar']]);
      wm2.get(k2) // "bar"
      
      

      WeakMap与Map的区别有两点£º

      首先£¬WeakMap只接受对象作为键名£¨null除外£©£¬不接受其他类型的值作为键名¡£

      const map = new WeakMap();
      map.set(1, 2)
      // TypeError: 1 is not an object!
      map.set(Symbol(), 2)
      // TypeError: Invalid value used as weak map key
      map.set(null, 2)
      // TypeError: Invalid value used as weak map key
      
      

      上面代码中£¬如果将数值1和Symbol值作为 WeakMap 的键名£¬都会报错¡£其次£¬WeakMap的键名所指向的对象£¬不计入垃圾回收机制¡£

      WeakMap的设计目的在于£¬有时我们想在某个对象上面存放一些数据£¬但是这会形成对于这个对象的引用¡£请看下面的例子¡£

      const e1 = document.getElementById('foo');
      const e2 = document.getElementById('bar');
      const arr = [
       [e1, 'foo 元素'],
       [e2, 'bar 元素'],
      ];
      
      

      上面代码中£¬e1和e2是两个对象£¬我们通过arr数组对这两个对象添加一些文字说明¡£这就形成了arr对e1和e2的引用¡£一旦不再需要这两个对象£¬我们就必须手动删除这个引用£¬否则垃圾回收机制就?#25442;?#37322;放e1和e2占用的内存¡£

      // 不需要 e1 和 e2 的时候
      // 必须手动删除引用
      arr [0] = null;
      arr [1] = null;
      
      

      五¡¢Map与其它数据结构的互相转换

      1.Map 转为数组£º

      Map 转为数组最方便的方法£¬就是使用扩展运算符£¨...£©¡£

      const myMap = new Map()
       .set(true, 7)
       .set({foo: 3}, ['abc']);
      [...myMap]
      // [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
      
      

      2.数组 转为 Map£º

      将数组传入 Map 构造函数£¬就可以转为 Map¡£

      new Map([
       [true, 7],
       [{foo: 3}, ['abc']]
      ])
      // Map {
      //  true => 7,
      //  Object {foo: 3} => ['abc']
      // }
      
      

      3.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 }
      
      

      4.对象转为 Map£º

      function objToStrMap(obj) {
       let strMap = new Map();
       for (let k of Object.keys(obj)) {
        strMap.set(k, obj[k]);
       }
       return strMap;
      }
      objToStrMap({yes: true, no: false})
      // Map {"yes" => true, "no" => false}
      
      

      5.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}'
      
      

      另一种情况是£¬Map 的键名有非字符串£¬这时可以选择转为数组 JSON¡£

      function mapToArrayJson(map) {
       return JSON.stringify([...map]);
      }
      let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
      mapToArrayJson(myMap)
      // '[[true,7],[{"foo":3},["abc"]]]'
      
      

      6.JSON 转为 Map£º

      JSON 转为 Map£¬正常情况下£¬所有键名都是字符串¡£

      function jsonToStrMap(jsonStr) {
       return objToStrMap(JSON.parse(jsonStr));
      }
      jsonToStrMap('{"yes": true, "no": false}')
      // Map {'yes' => true, 'no' => false}
      
      

      但是£¬有一种特殊情况£¬整个 JSON 就是一个数组£¬且每个数组成员本身£¬?#36136;?#19968;个有两个成员的数组¡£这时£¬它可以一一对应地转为 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相关内容感兴趣的读者可查看本站专题£º¡¶JavaScript数组操作技巧总结¡·¡¢¡¶JavaScript排序算法总结¡·¡¢¡¶JavaScript数学运算用法总结¡·¡¢¡¶JavaScript数据结构与算法技巧总结¡·¡¢¡¶JavaScript遍历算法与技巧总结¡·¡¢¡¶JavaScript查找算法技巧总结¡·及¡¶JavaScript错误与调试技巧总结¡·

      希望本文所述?#28304;?#23478;JavaScript程序设计有所帮助¡£

      相关文章

      最新评论

      3dÊÔ»úºÅÖвÊÍø

        1. <output id="hzk7v"><pre id="hzk7v"><address id="hzk7v"></address></pre></output>
          <output id="hzk7v"></output>
        2. <nav id="hzk7v"><i id="hzk7v"><em id="hzk7v"></em></i></nav>
        3. <listing id="hzk7v"><delect id="hzk7v"><em id="hzk7v"></em></delect></listing>

            1. <output id="hzk7v"><pre id="hzk7v"><address id="hzk7v"></address></pre></output>
              <output id="hzk7v"></output>
            2. <nav id="hzk7v"><i id="hzk7v"><em id="hzk7v"></em></i></nav>
            3. <listing id="hzk7v"><delect id="hzk7v"><em id="hzk7v"></em></delect></listing>