zoukankan      html  css  js  c++  java
  • ES6 中的 Set

    收录待用,修改转载已取得腾讯云授权


    作者:kurtshen

    ES6 新增了几种集合类型,本文主要介绍Set以及其使用。

    其基本描述为

    Set对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。

    它的声明

    new Set([iterable]);

    其中iterable是一个可迭代对象,其中的所有元素都会被加入到 Set 中。null被视作 undefined。也可以不传入[iterable],通过其add方法来添加元素。

    对于ruby或者是python比较熟悉的同学可能会比较了解set这个东东。它是ES6 新增的有序列表集合,它不会包含重复项。

    Set的属性

    • Set.prototype.size:返回Set实例的成员数量。
    • Set.prototype.constructor:默认的构造Set函数。

    Set方法

    • add(value):添加某个值,返回Set结构本身。
    • delete(value):删除某个值,返回一个布尔值,表示删除成功。
    • has(value):返回一个布尔值,表示参数是否为Set的成员。
    • clear():清除所有成员,没有返回值。
    • keys() :返回一个键名的遍历器
    • values() :返回一个值的遍历器
    • entries() :返回一个键值对的遍历器
    • forEach():使用回调函数遍历每个成员

    例子

    先借用之前看过的一篇英文blog的例子。地址请戳Removing Elements from JavaScript Arrays

    总所周知,数组是没有remove这个方法的。当我们需要从一个数组里面移除一个特定的元素时,我们通常会怎么写?

    在es6之前,我们会这么写

    function remove(array, element) {
        const index = array.indexOf(element);
        array.splice(index, 1);
    }
    
    

    然后我们可以这么用

    const arr = ["a", "e", "i", "o", "u", "x"];
    arr; //["a", "e", "i", "o", "u", "x"]
    
    // 移除其中的“x”
    remove(arr, "x");
    arr; // ["a", "e", "i", "o", "u"]
    
    // 细心的同学会发现我们前面那么写的问题,如果我们再次移除“x”的话,会发生移除最后一个元素
    remove(arr, "x");
    arr; // ["a", "e", "i", "o"]
    
    

    当数组查找不到某元素时会返回-1,则数组的splice会从末尾往前,移除了最后一个元素,于是我们会这么写

    function remove(array, element) {
        const index = array.indexOf(element);
    
        if (index !== -1) {
            array.splice(index, 1);
        }
    }
    
    

    这样的话我们就每次总是需要去检测index的值。

    我们还可以用filter来写remove,这样则返回一个新的数组

    function remove(array, element) {
        return array.filter(e => e !== element);
    }
    
    

    那么有了Set我们能怎写?其实也不需要写,因为set其初始化可以接受一个数组,作为构造参数,另外自带了一个delete的方法

    const set = new Set(["a", "e", "i", "o", "u", "x"]);
    set.delete("x"); // true
    set; // Set {"a", "e", "i", "o", "u"}
    
    set.delete("x"); // false
    set; // Set {"a", "e", "i", "o", "u"}
    
    

    好像蛮好的,但其实Set集合中的值是不能重复的,如果所需要的数据结构是要允许有重复项的,那么Set也没有什么用。

    Set中值的相等是这么说的

    因为 Set 中的值总是唯一的,所以需要判断两个值是否相等。判断相等的算法与严格相等(=操作符)不同。具体来说,对于 Set , +0 (+0 严格相等于-0)和-0是不同的值。尽管在最新的 ECMAScript 6规范中这点已被更改。从Gecko 29.0和 recent nightly Chrome开始,Set 视 +0 和 -0 为相同的值。另外,NaN和undefined都可以被存储在Set 中, NaN之间被视为相同的值(尽管 NaN ! NaN)。

    另一个例子

    既然它的值是唯一的,那么我们是不是可以用它来实现数组去重?

    原先我们去重可能会这么写

    let arr = [1,'1', 2, 3, 2, 4, 5, 4, 1];
    let arr_unique = arr.filter(function(item, index, array) {
    return array.indexOf(item, index + 1) === -1;
    });
    arr_unique;//["1", 3, 2, 5, 4, 1]
    
    

    或者利用对象key的唯一性,这么写

    let arr = [1,'1', 2, 3, 2, 4, 5, 4, 1];
    let tmpObj = {};
    let arr_unique = [];
    arr.forEach(function(a) {
      let key = (typeof a) + a;
      if (!tmpObj[key]) {
        tmpObj[key] = true;
        arr_unique.push(a);
      }
    });
    arr_unique;//[1, "1", 2, 3, 4, 5]
    
    

    于是现在还能这么写

    let arr = [1,'1', 2, 3, 2, 4, 5, 4, 1];
    let set = new Set(arr);
    let arr_unique = Array.from(set);//Array新增了一个静态方法Array.from,可以把类似数组的对象转换为数组
    arr_unique;//[1, "1", 2, 3, 4, 5]
    
    

    除了Array.from,我们也可以这么转化数组

    let set = new Set(['a','b','c']);
    let arr = [...set];
    arr;//['a','b','c']
    
    

    而利用Array与Set的相互转化,还可以很容易地实现并集(Union)和交集(Intersect)

    let a = new Set([1, 2, 3]);
    let b = new Set([4, 3, 2]);
    let union = new Set([...a, ...b]);
    union;// [1, 2, 3, 4]
    let intersect = new Set([...a].filter(x => b.has(x)));
    intersect;// [2, 3]
    
    

    总结

    与Array相比:

    • Set中存储的元素是唯一的,而Array中可以存储重复的元素。
    • Set中遍历元素的方式:Set通过for…of…,而Array通过for…in…。
    • Set是集合,不能像数组用下标取值。

    原文链接:http://ivweb.io/topic/582925cd9554d860548c1fa3


    原文链接:https://www.qcloud.com/community/article/592399001489391635

  • 相关阅读:
    【强行点出机械师天赋,修复无脸男储钱罐】
    【自由随想录(二)】
    【自由随想录(一)】
    iOS Alamofire插件使用方法
    iOS获取设备ip地址(OC版)
    获取位置
    objective-c 开发最简单的UITableView时数据进不去的问题
    java 获取真实IP
    数据库添加外键
    mysql 清库
  • 原文地址:https://www.cnblogs.com/liuliliuli2017/p/6838255.html
Copyright © 2011-2022 走看看