zoukankan      html  css  js  c++  java
  • ES6之map与set

    SET

    ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。
    1     const s = new Set();
    2      
    3     [2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
    4      
    5     for (let i of s) {
    6     console.log(i);
    7     }
    8     // 2 3 5 4

    上面代码通过add方法向 Set 结构加入成员,结果表明Set 结构不会添加重复的值。

    1     // 例一
    2     const set = new Set([1, 2, 3, 4, 4]);
    3     [...set]
    4     // [1, 2, 3, 4]
    5      
    6     // 例二
    7     const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
    8     items.size // 5

    上面代码中,也展示了一种去除数组重复成员的方法

    1     // 去除数组的重复成员
    2     [...new Set(array)]

    还有一种函数法数组去重

    1     function dedupe(array) {
    2     return Array.from(new Set(array));
    3     }
    4      
    5     dedupe([1, 1, 2, 3]) // [1, 2, 3]

    Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。下面先介绍四个操作方法。

    • add(value):添加某个值,返回Set结构本身。
    • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
    • has(value):返回一个布尔值,表示该值是否为Set的成员。
    • clear():清除所有成员,没有返回值。
     1     s.add(1).add(2).add(2);
     2     // 注意2被加入了两次
     3      
     4     s.size // 2
     5      
     6     s.has(1) // true
     7     s.has(2) // true
     8     s.has(3) // false
     9      
    10     s.delete(2);
    11     s.has(2) // false

     Set 结构的实例有四个遍历方法,可以用于遍历成员。

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

    由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。
     1     let set = new Set(['red', 'green', 'blue']);
     2      
     3     for (let item of set.keys()) {
     4     console.log(item);
     5     }
     6     // red
     7     // green
     8     // blue
     9      
    10     for (let item of set.values()) {
    11     console.log(item);
    12     }
    13     // red
    14     // green
    15     // blue
    16      
    17     for (let item of set.entries()) {
    18     console.log(item);
    19     }
    20     // ["red", "red"]
    21     // ["green", "green"]
    22     // ["blue", "blue"]

    Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法。这意味着,可以省略values方法,直接用for...of循环遍历 Set

    1     let set = new Set(['red', 'green', 'blue']);
    2      
    3     for (let x of set) {
    4     console.log(x);
    5     }
    6     // red
    7     // green
    8     // blue

    (2)forEach()

    Set结构的实例的forEach方法,用于对每个成员执行某种操作,没有返回值。

    1     let set = new Set([1, 2, 3]);
    2     set.forEach((value, key) => console.log(value * 2) )
    3     // 2
    4     // 4
    5     // 6

    (3)遍历的应用

    扩展运算符(...)内部使用for...of循环,所以也可以用于 Set 结构。

    1     let set = new Set(['red', 'green', 'blue']);
    2     let arr = [...set];
    3     // ['red', 'green', 'blue']

    扩展运算符和 Set 结构相结合,就可以去除数组的重复成员。

    1     let arr = [3, 5, 2, 2, 5, 5];
    2     let unique = [...new Set(arr)];
    3     // [3, 5, 2]

    而且,数组的mapfilter方法也可以用于 Set 了。

    1     let set = new Set([1, 2, 3]);
    2     set = new Set([...set].map(x => x * 2));
    3     // 返回Set结构:{2, 4, 6}
    4      
    5     let set = new Set([1, 2, 3, 4, 5]);
    6     set = new Set([...set].filter(x => (x % 2) == 0));
    7     // 返回Set结构:{2, 4}

    因此使用 Set 可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)。

     1     let a = new Set([1, 2, 3]);
     2     let b = new Set([4, 3, 2]);
     3      
     4     // 并集
     5     let union = new Set([...a, ...b]);
     6     // Set {1, 2, 3, 4}
     7      
     8     // 交集
     9     let intersect = new Set([...a].filter(x => b.has(x)));
    10     // set {2, 3}
    11      
    12     // 差集
    13     let difference = new Set([...a].filter(x => !b.has(x)));
    14     // Set {1}

    如果想在遍历操作中,同步改变原来的 Set 结构,目前没有直接的方法,但有两种变通方法。一种是利用原 Set 结构映射出一个新的结构,然后赋值给原来的 Set 结构;另一种是利

    用Array.from方法。

    MAP

    Set类似于数组,而Map就类似于键值对(Key, Value);
     
    ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
     1     const map = new Map([
     2     ['name', '张三'],
     3     ['title', 'Author']
     4     ]);
     5      
     6     map.size // 2
     7     map.has('name') // true
     8     map.get('name') // "张三"
     9     map.has('title') // true
    10     map.get('title') // "Author"15 
    16     const items = [
    17     ['name', '张三'],
    18     ['title', 'Author']
    19     ];
    20      
    21     const map = new Map();
    22      
    23     items.forEach(
    24     ([key, value]) => map.set(key, value)
    25     );

    上面代码在新建 Map 实例时,就指定了两个键name和title。Map构造函数接受数组作为参数,实际上执行的是下面的算法。

     如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,包括0和-0,布尔值true和字符串true则是两个不同的键。另外,undefined和null也是两个不

    同的键。虽然NaN不严格相等于自身,但 Map 将其视为同一个键。

     1     let map = new Map();
     2      
     3     map.set(-0, 123);
     4     map.get(+0) // 123
     5      
     6     map.set(true, 1);
     7     map.set('true', 2);
     8     map.get(true) // 1
     9      
    10     map.set(undefined, 3);
    11     map.set(null, 4);
    12     map.get(undefined) // 3
    13      
    14     map.set(NaN, 123);
    15     map.get(NaN) // 123

    Map有size()属性,查看Map对象大小

    操作方法

    • set(key , value):添加元素
    • get(Key):获取value
    • delete(key):删除元素
    • has(key):返回一个布尔值,表示是否存在该key的成员
    • clear():清除所有元素,没有返回值

    遍历方法

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

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

     需要特别注意的是,Map 的遍历顺序就是插入顺序。

     1     const map = new Map([
     2     ['F', 'no'],
     3     ['T', 'yes'],
     4     ]);
     5      
     6     for (let key of map.keys()) {
     7     console.log(key);
     8     }
     9     // "F"
    10     // "T"
    11      
    12     for (let value of map.values()) {
    13     console.log(value);
    14     }
    15     // "no"
    16     // "yes"
    17      
    18     for (let item of map.entries()) {
    19     console.log(item[0], item[1]);
    20     }
    21     // "F" "no"
    22     // "T" "yes"
    23      
    24     // 或者
    25     for (let [key, value] of map.entries()) {
    26     console.log(key, value);
    27     }
    28     // "F" "no"
    29     // "T" "yes"
    30      
    31     // 等同于使用map.entries()
    32     for (let [key, value] of map) {
    33     console.log(key, value);
    34     }
    35     // "F" "no"
    36     // "T" "yes"

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

     1     const map = new Map([
     2     [1, 'one'],
     3     [2, 'two'],
     4     [3, 'three'],
     5     ]);
     6      
     7     [...map.keys()]
     8     // [1, 2, 3]
     9      
    10     [...map.values()]
    11     // ['one', 'two', 'three']
    12      
    13     [...map.entries()]
    14     // [[1,'one'], [2, 'two'], [3, 'three']]
    15      
    16     [...map]
    17     // [[1,'one'], [2, 'two'], [3, 'three']]

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

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

    Map可以跟数组,对象,JSON相互转换,这里记录一下与JSON的转换

     --Map 转为 JSON

    Map 转为 JSON 要区分两种情况。一种情况是,Map 的键名都是字符串,这时可以选择转为对象 JSON。

    1     function strMapToJson(strMap) {
    2     return JSON.stringify(strMapToObj(strMap));
    3     }
    4      
    5     let myMap = new Map().set('yes', true).set('no', false);
    6     strMapToJson(myMap)
    7     // '{"yes":true,"no":false}'

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

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

    --JSON 转为 Map

    JSON 转为 Map,正常情况下,所有键名都是字符串。
    1     function jsonToStrMap(jsonStr) {
    2     return objToStrMap(JSON.parse(jsonStr));
    3     }
    4      
    5     jsonToStrMap('{"yes": true, "no": false}')
    6     // Map {'yes' => true, 'no' => false}

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

    1     function jsonToMap(jsonStr) {
    2     return new Map(JSON.parse(jsonStr));
    3     }
    4      
    5     jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
    6     // Map {true => 7, Object {foo: 3} => ['abc']}
  • 相关阅读:
    vue 中的虚拟dom
    Vue基操
    表头固定,表的主体设置滚动条,同时解决错位问题
    AngularJS处理服务器端返回的JSON数据的格式问题
    jQuery ajax-param()
    Bootstrap中内联单选按钮
    angularJS中控制器和作用范围
    如何理解MVC?
    CSS3动画简介以及动画库animate.css的使用
    UGUI实现打字的效果
  • 原文地址:https://www.cnblogs.com/yy136/p/9745197.html
Copyright © 2011-2022 走看看