ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的(自带去重),没有重复的值。Set
本身是一个构造函数,用来生成 Set 数据结构。
let set = new Set([1,2,3,4,5,6,7,2,3,4,5]);
console.log(set); //Set { 1, 2, 3, 4, 5, 6, 7 }
console.log(set.size); //7
数据操作
add(value)
:添加一个值,返回Set结构本身delete(value)
:删除一个值,返回一个boolean表示删除是否成功has(value)
:返回一个boolean表示该值是否为Set的成员clear()
:清除所有Set内所有成员
Set
函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
//例一
const set = new Set([1,2,3,4,5,6,7,5,4,3,2]);
console.log([...set]); //[1, 2, 3, 4, 5, 6, 7]
//例二
const set = new Set(document.querySelectorAll("div"));
使用set函数去重
//数组去重
//方法1
var arr = [1,2,3,4,5,6,7,4,3,2,4,5,76,3];
console.log(new Set(arr)); //Set { 1, 2, 3, 4, 5, 6, 7, 76 }
console.log([...new Set(arr)]); //[1, 2, 3, 4, 5, 6, 7, 76]
//方法2:利用Array.from( )见下文
function dedupe(arr){
return Array.from(new Set(arr));
}
dedupe([1,2,3,2,1]);
//字符串去重
var str = "123456667";
console.log([...new Set(str)].join());
向Set加入值时不会发生类型转换
(在Set内部NaN是相等的,向Set加入NaN时只能加入一个)
(两个对象总是不相等)
let set = new Set([1,2,3,4,5]);
set.add(6);
set.add("6");
set.add(NaN);
set.add(NaN);
set.add({});
set.add({});
console.log(set); //Set { 1, 2, 3, 4, 5, 6, '6', NaN, {}, {} }
Set结构转数组:Array.from()
const a = new Set([1,2,3,4,5,6,7]);
const arr = Array.from(a); //[1, 2, 3, 4, 5, 6, 7]
遍历操作(.keys() / .values() / .entries() / .forEach() )
-
keys
方法、values
方法、entries
方法返回的都是遍历器对象.由于 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 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values
方法。这意味着,可以省略values
方法,直接用for...of
循环遍历 Set。
let set = new Set(["red","green","blue"]);
for(let item of set){
console.log(item);
}
// red
// green
// blue
forEach()
Set 结构的实例与数组一样,也拥有forEach
方法,用于对每个成员执行某种操作,没有返回值。
let set = new Set([1,2,3,5,76]);
/* set.forEach(function(value,key){
console.log(key + " : " + value);
}) */
set.forEach((value,key) => console.log(key + " : " + value));
遍历的应用
- 扩展运算符(
...
)内部使用for...of
循环,所以也可以用于 Set 结构。(去重部分已展示) - 数组的
map
和filter
方法也可以间接用于 Set 了。
let set = new Set([1,2,3,4,5]);
//map方法
set = new Set([...set].map(x => x * 2));
console.log(set); //Set { 2, 4, 6, 8, 10 }
//filter方法
set = new Set([...set].filter(x => (x % 2) == 0));
console.log(set); //Set { 2, 4, 6, 8, 10 }
- 实现并集/交集/差集功能
let a = new Set([1,2,3,4]);
let b = new Set([3,4,5,6]);
//并集
let union = new Set([...a,...b]);
console.log(union); //Set { 1, 2, 3, 4, 5, 6 }
//交集
let intersect = new Set([...a].filter(x => b.has(x)));
console.log(intersect); //Set { 3, 4 }
//(a相对于b的)差集
let difference = new Set([...a].filter(x => !b.has(x)));
console.log(difference); //Set { 1, 2 }
在遍历中修改原来的Set结构
//方法1
let set = new Set([1,2,3]);
set = new Set([...set].map(val => val * 2));
console.log(set); //Set { 2, 4, 6 }
//方法2
set = new Set(Array.from(set,val => val * 2));
console.log(set); //Set { 4, 8, 12 }
整篇是参考阮一峰的教学写的,建议大家可以去这个网址看,很全面详细
https://es6.ruanyifeng.com/