Set是ES6新增的数据结构,类似于数组,但它的一大特性就是所有元素都是唯一的,没有重复的值,我们一般称为集合。Set是一个构造函数,用来生成Set的数据结构。
Set打印出来的数据结构,是一个对象。
var set=new Set([1,2,3])
console.log(set) // Set(3) {1,2,3}
要创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set。
//初始化一个Set ,需要一个Array数组,要么空Set
var set = new Set([1,2,3,5,6])
console.log(set) // {1, 2, 3, 5, 6}
//添加元素 add()
//返回 Set 结构本身,当添加实例中已经存在的元素,set不会进行处理添加。也可以采用链式写法
set.add(7) //{1, 2, 3, 5, 6, 7}
//删除元素 delete(), 返回一个布尔值。
set.delete(3) // {1, 2, 5, 6, 7}
//检测是否含有此元素,有为true,没有则为false
set.has(2) //true
//清除所有元素,没有返回值。
var arr = [2, 3, 5, 3, 5, 2];
var arrSet = new Set(arr);
console.log(arrSet); // Set(6) {2, 3, 5}
//方法一:用ES6的...结构
let newArr1 = [...arrSet];
console.log(newArr1 ); // [2, 3, 5]
//方法二:用Array.from()将类数组转化为数组
let newArr2 = Array.from(arrSet);
console.log(newArr2 ); // [2, 3, 5]
var str = "2234332244";
var newStr = [...new Set(str)].join("");
console.log(newStr); //234
let a = new Set([1, 2, 3]),
b = new Set([2, 3, 4]);
//并集
var res1 = new Set([...a, ...b]);
console.log('并集:', res1);
//交集
var res2 = new Set([...a].filter(x => b.has(x)));
console.log('交集:', res2);
//差集(a 相对于 b)
var res3 = new Set([...a].filter(x => !b.has(x)));
console.log('差集:', res3);
//并集 Set(4) {1,2,3,4}
//交集 Set(2) {2,3}
//差集 Set(1) {1}
Set结构的实例有四个遍历方法,可用于遍历成员。
keys(), values(), entries()返回的都是遍历器对象。
Set结构没有键名,只有键值,所以keys()和values()方法的行为完全一致。
var list = new Set(["a", 1, 2, 3]);
for(let key of list.keys()) {
console.log(key); // a 1 2 3
}
var list = new Set(["a", 1, 2, 3]);
for(let value of list.values()) {
console.log(value); // a 1 2 3
}
var list = new Set(["a", 1, 2, 3]);
for(let row of list.entries()) {
console.log(row); // ["a", "a"] [1, 1] [2, 2] [3, 3]
}
var list = new Set(["a", 1, 2, 3]);
list.forEach((value, key) => {
console.log(key + ":" + value); // a:a 1:1 2:2 3:3
});
JS的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。为了解决这个问题,最新的ES6规范引入了新的数据类型Map。
Map类似于对象,数据结构是一个键值对的结构,但是“键”的范围不限制于字符串,各种类型的值(包含对象)都可以当作键。
Map 也可以接受一个数组作为参数,数组的成员是一个个表示键值对的数组。注意Map里面也不可以放重复的项。
一个key只能对应一个value,多次对一个key放入value,后面的值会把前面的值覆盖掉;
初始化Map需要一个二维数组,或者直接初始化一个空Map。
//初始化`Map`需要一个二维数组(请看 Map 数据结构),或者直接初始化一个空`Map`
let map = new Map();
//添加key和value值
map.set('Amy','女')
map.set('liuQi','男')
//是否存在key,存在返回true,反之为false
map.has('Amy') //true
map.has('amy') //false
//根据key获取value
map.get('Amy') //女
//删除 key为Amy的value
map.delete('Amy')
map.get('Amy') //undefined 删除成功
map.forEach(function(key,value){
console.log(key,value);
});
//函数中第一个参数是属性,第二个参数是属性值
①for(let item of map){
}
遍历结果是数组
②for(let item of map.values()){
}
遍历属性值
③for(let item of map.keys()){
}
遍历属性
for(let item of map.entries()){
}
遍历结果同forEach
(1)Object的key只能是字符串(String)或符号(Symbol),
而Map的key可以是任意值,包括函数,对象(object)或者任何原始值(primitive value)。
(2)对于Map来说,可以通过size属性直接获取key的个数,
而Object则需要Object.keys(xxx).length来间接获取自身属性的个数。
(3)Map实例是一个iterable对象,可以直接用来遍历,
而Object需要先获取它的key,再使用key进行遍历。
(4)Object可以有原型对象,自身属性可能会无意间与原型属性相冲突。
(虽然ES2015中可以通过Object.create(null)来创建一个无原型的对象。)
(5)Map key的添加删除操作更加高效。
map和set一样是关联式容器,它们的底层容器都是红黑树。
两种方法具有极快的查找速度。
Map 和 Set 都不允许键重复。
初始化需要值不一样,Map需要的是一个二维数组,而Set 需要的是一维 Array 数组。
Map 是键值对的存在,键和值是分开的;Set 没有 value 只有 key,value 就是 key;