zoukankan      html  css  js  c++  java
  • 01快速入门-04-Map、Set和iterable(ES6)

    1、Map

    我们知道,在JS中其实对象的方式就跟Java中的Map极为相似,即键值对的方式。JS中,key必须是字符串,实际上Number等值作为key也是合理的,所以为了解决这个问题,在最新的ES6规范中加入了新的数据类型 Map 。
    var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]); 
    m.get('Michael'); // 95

    Map类似二维数组,且每个元素数组的长度为2,其中索引0作为键key,索引1作为值value。所以初始化Map需要一个二维数组,或者直接初始化一个空Map。(常用方法:get获取、set存储、delete删除、has判断包含)
    var m = new Map(); // 空Map
    m.set('Adam', 67); // 添加新的key-value
    m.set('Bob', 59);
    m.has('Adam'); // 是否存在key 'Adam' --> true
    m.get('Adam'); // 67
    m.delete('Adam'); // 删除key 'Adam'
    m.get('Adam'); // undefined

    同样,作为Map,如果多次对同一个key设置不同的value,之前的值会被替换掉。

    2、Set

    Set和Map类似也是一组key的集合,但是不存储value,且key不能重复

    创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set:
    var s1 = new Set(); // 空Set
    var s2 = new Set([1, 2, 3]); // 含1, 2, 3

    重复元素在Set中自动被过滤:
    var s = new Set([1, 2, 3, 3, '3']);
    s; // Set {1, 2, 3, "3"}  --> 注意数字3和字符串'3'是不同的元素

    通过add(key)方法可以添加元素到Set中,可以重复添加,但不会有效果;通过delete(key)方法可以删除元素。

    可以利用这个特性对数组进行去重
    'use strict';
    // var set = new Set([1,2,1,2,2,1]);
    
    var arr = [1,2,1,2,2,1];
    
    //new Set 数组去重
    function unique(arr){
      return Array.from(new Set(arr));
    };
    //使用ES6的方法可以去重.
    console.log(unique(arr));

    3、iterable

    Array可以通过下标循环遍历,但是Map和Set则无法,所以ES6标准引入了新的iterable类型,Array、Map、Set都属于iterable类型。

    回顾:对象可以通过 for in 的方式遍历对象所有属性,虽然说实际上Array也是一个对象,但是用 for in 遍历数组会出现问题,具体的可以戳这里,Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。当我们手动给Array对象添加了额外的属性后,for ... in循环将带来意想不到的意外效果。

    所以对于数组,我们还是尽量避免用 for in 的方式,要么老老实实用 for(var i = 0; i < arr.length; i++) 的方式,要么接着往下看:

    具有iterable类型的集合,可以通过 for ... of 循环来遍历,直接遍历其元素,而不单纯是索引
    'use strict';
    var a = [1, 2, 3];
    for (var x of a) {
    	alert(x);
    }

    遍历集合用法如下
    var a = ['A', 'B', 'C'];
    var s = new Set(['A', 'B', 'C']);
    var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
    for (var x of a) { // 遍历Array
        alert(x);
    }
    for (var x of s) { // 遍历Set
        alert(x);
    }
    for (var x of m) { // 遍历Map
        alert(x[0] + '=' + x[1]);
    }

    还有更好的方式,直接使用 iterable 内置的 forEach 方法,它接收一个函数,每次迭代会自动回调该函数,以Array为例:
    var a = ['A', 'B', 'C'];
    a.forEach(function(element, index, array){
        //element --> 指向当前元素的值
        //index --> 指向当前索引
        //array --> 指向Array对象本身
        alert("element-->"+element);
        alert("index-->"+index);
        alert("array-->"+array);
    });

    这里的element、index、array的命名是不固定的,但是固定位置的含义是如上所示的固定的,有一点点类似Java中的方法重载。试一下下面的代码你就明白了:
    //Array
    var a = ['A', 'B', 'C'];
    a.forEach(function(element, index, array){
        //element --> 指向当前元素的值
        //index --> 指向当前索引
        //array --> 指向Array对象本身
        alert(element); //首次输出A
        alert(element); //首次输出0
        alert(element);
    });

    而Map和Set的话:

    //Map
    var b = new Map([['indexA', 'a'],['indexB', 'b'],['indexC', 'c']]);
    b.forEach(function(value, key, map){
        //value --> 指向当前元素的值
        //key --> 指向当前键
        //map --> 指向Map对象本身
        alert(value); //首次输出a
        alert(key);  //首次输出indexA
        alert(map);
    });
    //Set
    var c = new Set(['a', 'b', 'c']);
    c.forEach(function(key, key, set){
        //key --> 指向当前键
        //key --> 指向当前键
        //set --> 指向Map对象本身
        alert(key); //首次输出a
        alert(key); //首次输出a
        alert(set);
    });

    ES6中迭代器部分,更多可以参考:[译]JavaScript ES6迭代器指南

  • 相关阅读:
    C++11 override和final
    C++11 类型推导auto
    C++11 强枚举类型
    C++11 explicit的使用
    《数据结构与算法之美》——冒泡排序、插入排序、选择排序
    《数据结构与算法之美》- 栈
    Spring Boot系列——AOP配自定义注解的最佳实践
    Spring Boot系列——死信队列
    Spring Boot系列——7步集成RabbitMQ
    让我头疼一下午的Excel合并单元格
  • 原文地址:https://www.cnblogs.com/deng-cc/p/6601836.html
Copyright © 2011-2022 走看看