zoukankan      html  css  js  c++  java
  • es6(三set和map数据结构)

    es6中提供了一个新的数据结构Set,他有点类似数组,但和数组不同的是,在里面你如果写入重复的值的话,他不会显示重复值。

    const s =new Set();
        [2,3,4,5,6,6,6,7,8,9].forEach(x => s.add(x));
        for (let i of s){
          console.log(i)
        }
    //2,3,4,5,6,7,8,9
    

      平常使用当然不需要像上面那样麻烦了,只需要最简单的方式来进行获取输出就行了

    // 用中括号括起来,可以得到不重复的数组,用大括号括起来,可以得到对象和总共多少个
    const set = new Set([1, 2, 3, 4, 4]);
    [...set]
    // [1, 2, 3, 4]
    {...set}
    //{4,array(3)}
    
    // .size的输出是直接获取有多少个不重复的对象
    const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
    items.size // 5
    

      往set中去添加对象,就像在函数中进行.push一样

    //用.add方法往set中添加对象,这里说明一下NAN值,在这最后输出的是一个NAN说明两个NAN是相等的
    let set = new Set();
    let a = NaN;
    let b = NaN;
    set.add(a);
    set.add(b);
    set // Set {NaN}
    
    //但是只要添加对象的话就不同了,两个对象是永远不相等的
    set.add({});
    set.size // 1
    
    set.add({});
    set.size // 2
    //上面可以看出,添加了两次对象最后输出的 值是2,说明两个相同的对象添加进去,不会出现去重现象
    

      介绍下四个操作方法

     - add(value):添加某个值,返回 Set 结构本身。
     - delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
     - has(value):返回一个布尔值,表示该值是否为Set的成员。
     - clear():清除所有成员,没有返回值。
    

      Array.from方法可以将Set结构转为数组(在我看来这个方法没啥用出都,直接用上面的方法就已经成为了数组,何必再去转一回呢)

    const items = new Set([1, 2, 3, 4, 5]);
    const array = Array.from(items);
    
    了解下就好
    function dedupe(array) {
      return Array.from(new Set(array));
    }
    
    dedupe([1, 1, 2, 3]) // [1, 2, 3]
    

      介绍四个遍历的方法

     - keys():返回键名的遍历器
     - values():返回键值的遍历器
     - entries():返回键值对的遍历器
     - forEach():使用回调函数遍历每个成员
    

      平常就直接用set结构就可以了,set的遍历顺序就是插入顺序,由于set结构没有键名只有键值,所以keys方法和values方法的行为是完全一样的

    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
    
    //entries方法,把键值和键名全都返回回来了
    for (let item of set.entries()) {
      console.log(item);
    }
    // ["red", "red"]
    // ["green", "green"]
    // ["blue", "blue"]
    

      set实现的并集,交集,差集

    let a = new Set([1, 2, 3]);
    let b = new Set([4, 3, 2]);
    
    // 并集
    let union = new Set([...a, ...b]);
    // Set {1, 2, 3, 4}
    
    // 交集
    let intersect = new Set([...a].filter(x => b.has(x)));
    // set {2, 3}
    
    // 差集
    let difference = new Set([...a].filter(x => !b.has(x)));
    // Set {1}
    

      weakSet结构和Set类似,但是weakSet结构只能放入对象,不能放入其他类型的值,创建一个新的weakSet数据结构,使用的时候会把成员转换成对象输出

    const a = [[1, 2], [3, 4]];
    const ws = new WeakSet(a);
    // WeakSet {[1, 2], [3, 4]}
    

      这里有个面向对象的问题说一下,可能理解的不全面,凑活着理解吧

    const b =[['3'] , ['4']]
        const ws = new WeakSet(b);
        console.log(ws)
    //WeakSet {_c: WeakSet}
    //    _c: WeakSet {Array(1), Array(1)}
    //    __proto__: WeakSet    
    
    如果
    const b = [3,4]
    const ws = new WeakSet(b);
    //这样就会报错的,因为b里面的值不是数组,是个number
    

      WeakSet 没有size属性,没有办法遍历它的成员。

    Map构造函数

    const map = new Map([
      ['name', '张三'],
      ['title', 'Author']
    ]);
    
    map.size // 2
    map.has('name') // true
    map.get('name') // "张三"
    map.has('title') // true
    map.get('title') // "Author"
    

      注意:只有同一个对象的引用,Map结构才视为同一个键

    const map = new Map();
    
    map.set(['a'], 555);
    map.get(['a']) // undefined
    

      

    //表面是针对同一个键,但实际上这是两个值,内存地址是不一样的,因此get方法无法读取该键,返回undefined
    const map = new Map();
    
    const k1 = ['a'];
    const k2 = ['a'];
    
    map
    .set(k1, 111)
    .set(k2, 222);
    
    map.get(k1) // 111
    map.get(k2) // 222
    

      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"
    上面代码最后的那个例子,表示 Map 结构的默认遍历器接口(Symbol.iterator属性),就是entries方法。
    
    map[Symbol.iterator] === map.entries
    // true
    

      Map转为数组结构,和set差不太多

    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']]
    

      与其他数据结构互相转换

    (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 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组。这时,它可以一一对应地转为 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']}
    

      

  • 相关阅读:
    PAT (Advanced Level) 1010. Radix (25)
    PAT (Advanced Level) 1009. Product of Polynomials (25)
    PAT (Advanced Level) 1008. Elevator (20)
    PAT (Advanced Level) 1007. Maximum Subsequence Sum (25)
    PAT (Advanced Level) 1006. Sign In and Sign Out (25)
    PAT (Advanced Level) 1005. Spell It Right (20)
    PAT (Advanced Level) 1004. Counting Leaves (30)
    PAT (Advanced Level) 1001. A+B Format (20)
    PAT (Advanced Level) 1002. A+B for Polynomials (25)
    PAT (Advanced Level) 1003. Emergency (25)
  • 原文地址:https://www.cnblogs.com/yishifuping/p/9990808.html
Copyright © 2011-2022 走看看