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是集合,不能像数组用下标取值。
原文链接:https://www.qcloud.com/community/article/592399001489391635
ES6 中的 Set的更多相关文章
- ES6中的模板字符串和新XSS Payload
ES6中的模板字符串和新XSS Payload 众所周知,在XSS的实战对抗中,由于防守方经常会采用各种各样严格的过滤手段来过滤输入,所以我们使用的XSS Payload也会根据实际情况作出各种各样的 ...
- ES5和ES6中的继承 图解
Javascript中的继承一直是个比较麻烦的问题,prototype.constructor.__proto__在构造函数,实例和原型之间有的 复杂的关系,不仔细捋下很难记得牢固.ES6中又新增了c ...
- ES6中块作用域之于for语句是怎样的?
在ES6中新加了快作用域的概念(C语言就有,作为类c语言的js,当然应该加上),算是很好理解. { let i; } console.log(i);// i is not defined 在代码块当中 ...
- ES6中的var let const应如何选择
javascript世界里面的每个人都在说有关ECMAScript 6 (ES6,也称作ES 2015)的话题,对象的巨大变化 ( 类 , super() , 等), 函数 (默认参数等), 以及模块 ...
- Nodejs与ES6系列4:ES6中的类
ES6中的类 4.1.class基本语法 在之前的javascript语法中是不存在class这样的概念,如果要通过构造函数生成一个新对象代码 function Shape(width,height) ...
- ES6中Arguments和Parameters用法解析
原文链接 译文 ECMAScript 6 (也称 ECMAScript 2015) 是ECMAScript 标准的最新版本,显著地完善了JS中参数的处理方式.除了其它新特性外,我们还可以使用rest参 ...
- ES6中的Class
对于javascript来说,类是一种可选(而不是必须)的设计模式,而且在JavaScript这样的[[Prototype]] 语言中实现类是很蹩脚的. 这种蹩脚的感觉不只是来源于语法,虽然语法是很重 ...
- ES5和ES6中对于继承的实现方法
在ES5继承的实现非常有趣的,由于没有传统面向对象类的概念,Javascript利用原型链的特性来实现继承,这其中有很多的属性指向和需要注意的地方. 原型链的特点和实现已经在之前的一篇整理说过了,就是 ...
- ES6中的高阶函数:如同 a => b => c 一样简单
作者:Sequoia McDowell 2016年01月16日 ES6来啦!随着越来越多的代码库和思潮引领者开始在他们的代码中使用ES6,以往被认为是"仅需了解"的ES6特性变成了 ...
- 深入理解 JavaScript 异步系列(3)—— ES6 中的 Promise
第一部分,Promise 加入 ES6 标准 原文地址 http://www.cnblogs.com/wangfupeng1988/p/6515855.html 未经作者允许不得转载! 从 jquer ...
随机推荐
- 洛谷P2657 [SCOI2009]windy数 [数位DP,记忆化搜索]
题目传送门 windy数 题目描述 windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和B,总共有多少个win ...
- BZOJ3262陌上花开(三维偏序问题(CDQ分治+树状数组))+CDQ分治基本思想
emmmm我能怎么说呢 CDQ分治显然我没法写一篇完整的优秀的博客,因为我自己还不是很明白... 因为这玩意的思想实在是太短了: fateice如是说道: 如果说对于一道题目的离线操作,假设有n个操作 ...
- apue第17章笔记
unix domain socket 关闭socket并不会删除文件,重复bind会失败.所以在bind之前要unlink该文件. open服务器的实现只是简单地看了一下,大致上就是通过unix do ...
- shell 文件合并,去重,分割
第一:两个文件的交集,并集前提条件:每个文件中不得有重复行1. 取出两个文件的并集(重复的行只保留一份)2. 取出两个文件的交集(只留下同时存在于两个文件中的文件)3. 删除交集,留下其他的行1. c ...
- sql 和xml
一·常用基本功能 表结果: 1. 1 <row> 2 <ID>1035</ID> 3 <Rate>6.12</Rate> 4 <Dat ...
- android jni c C++ 实现下载
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha android jni c C++ 实现下载
- 安卓 自定义ViewGroup
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 指定的 布局参数 在计算时候方法 中 计算 所有 子视图的 宽高, 然后根据这些 计算出 ...
- [BZOJ4196][NOI2015]软件包管理器(树链剖分)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2166 Solved: 1253[Submit][Sta ...
- POJ3233 Matrix Power Series 矩阵乘法
http://poj.org/problem?id=3233 挺有意思的..学习到结构体作为变量的转移, 题意 : 给定矩阵A,求A + A^2 + A^3 + ... + A^k的结果(两个矩阵相加 ...
- Arab Collegiate Programming Contest 2012 J- Math Homework
思路:由于只有1-6这几个数,而这几个数的最小公倍数是60,所以只需要求出60以内有多少满足条件的数即可. 再就是求出对于给定的n,求出60的倍数.然后就是怎样求的问题了. 首先可以写成如下形式: ...