ES6中的Set与Map

Set与Map都是ES6标准中新增的数据结构.

Set

Set是一种类似数组的数据结构,也是一种数据集合,但并不是数组.区别在于Set的值不能重复,Set本身是一个构造函数,用来生成Set数据结构.使用Set有两种数据传入的方式,一种就是在实例化Set的时候传入一个数组,另外一种是为Set实例使用add方法.

数据传入

Set是一个构造函数,在实例化对象的时候,传入一个数组

let arr = [1,1,2,2,3,3,5,6,3,2,4,5];
let s = new Set(arr);
console.log(s);  //Set { 1, 2, 3, 5, 6, 4 }

从示例中可以看出,Set数据结构为我们解决了一个数组的问题,数据去重的问题.这个问题在数组中需要我们做处理,而到了Set中,直接就把重复的数据去除掉了.虽然去重了,但是数据类型变了,变成了Set的类型了,并不是数组了.如果我们的代码中必须要使用数组的话,而我们的去重处理恰恰又是使用的Set,那么我们就需要多做一步了,需要将Set数据结构转换为数组类型.

Set转换为Array

set可以与扩展运算符的结合使用,可以完成数组去重后的浅拷贝

let arr = [1,1,2,2,3,3,5,6,3,2,4,5];
let s = new Set(arr);
let newArr = [...s];
console.log(Array.isArray(newArr)); //true

说明我们已经将Set转换成Array了.

Set实例使用add方法添加项

let arr = [1,1,2,2,3,3,5,6,3,2,4,5];
let s = new Set(arr);
let newArr = [...s];
console.log(Array.isArray(newArr)); //true
s.add(9);
console.log(s);//Set { 1, 2, 3, 5, 6, 4, 9 }

也可以通过Array的from方法将Set转换为Array.

let arr = [1,2];
const s1 = new Set(arr);
console.log(Array.isArray(s1)); //false
let newArr = Array.from(s1);
console.log(Array.isArray(newArr)); //true

然后这里就有一个隐藏的技术点需要来总结下了:Set和Array的相互转换:

Set转换为数组

let arr = [1,2];
const s1 = new Set(arr);
console.log(Array.isArray(s1)); //false
let newArr = Array.from(s1);
let newArr2 = [...s1];
console.log(Array.isArray(newArr)); //true
console.log(Array.isArray(newArr2)); //true

数组转换为Set

let arr = [1,2];
const s1 = new Set(arr);
console.log(s1); //Set { 1, 2 }

Set的长度

前面我们提到Set是一个种类数组的数据结构,数组有一个使用频率非常高的属性,就是length,很多时候我们会根据数组的length属性来做一些操作,那么Set是否和数组一样也有这个属性呢?

Set也有这个属性,但是和数组不同的是,Set的这个length属性是Set这个类的,而不是Set的实例对象的.如:

let arr = [1,1,2,2,3,3,5,6,3,2,4,5];
let s = new Set(arr);
console.log(s); //Set { 1, 2, 3, 5, 6, 4 }
console.log(Set.length); //0,说明Set这个类型的length属性为0,和具体的实例没有关系
console.log(s.length); //undefined,说明了Set的实例对象是没有这个属性的

在Set中,是通过实例对象的size属性来获取实例的项的个数的.

let arr = [1,1,2,2,3,3,5,6,3,2,4,5];
let s = new Set(arr);
console.log(s);
console.log(Set.length); //0
console.log(s.length); //undefined
console.log(s.size);//6

Set常用方法

1.判断set实例中是否有某个值: 

has(value):返回值:Boolean,true、false

let arr = [1,1,2,2,3,3,5,6,3,2,4,5];
let s = new Set(arr);
console.log(s.has(12));  //false
console.log(s.has(4));  //true

2.添加元素

add(value):向set末尾添加值为value的项

let arr = [1,1,2,2,3,3,5,6,3,2,4,5];
let s = new Set(arr);
console.log(s);  //Set { 1, 2, 3, 5, 6, 4 }
s.add(22);
console.log(s);  //Set { 1, 2, 3, 5, 6, 4, 22 }
let arr = [1,2];
const s1 = new Set(arr);
let obj = {a:3,b:4};
s1.add(obj);
console.log(s1); //Set { 1, 2, { a: 3, b: 4 } }

Set可以通过add添加对象元素.

3.清空元素

clear():清空set实例

let arr = [1,1,2,2,3,3,5,6,3,2,4,5];
let s = new Set(arr);
console.log(s); //Set { 1, 2, 3, 5, 6, 4 }
s.clear();
console.log(s); //Set {}

4.移除Set中与这个值相等的元素

delete(value):移除set中值为value的元素

let arr = [1,1,2,2,3,3,5,6,3,2,4,5];
let s = new Set(arr);
console.log(s); //Set { 1, 2, 3, 5, 6, 4 }
s.delete(3);
console.log(s); //Set { 1, 2, 5, 6, 4 }

5.数据遍历

既然Set是类数组的数据结构,那么在使用中肯定就会涉及到对数据的遍历.

forEach(callback,[args]):

callback:每个元素都会执行的函数,有3个参数:

  • 元素的值
  • 元素的索引
  • 将要遍历的集合对象

Set对象是没有索引值的(keys),所以callback的前2个参数都是Set中的元素值(values).

let arr = [1,2];
const s1 = new Set(arr);
s1.add(42);
console.log(s1); //Set { 1, 2, 42 }
s1.forEach((item)=>{
    console.log(item); //1、2、42
});

for……of:遍历set,可以直接是一个set实例,可以是一个set实例的values,也可以是set的keys

let arr = [1,2];
const s1 = new Set(arr);
for(let item of s1){
    console.log(item); //1、2
}
for(let item of s1.values()){
    console.log(item);//1、2
}
for(let item of s1.keys()){
    console.log(item);//1、2
}

for(let [key,value] of s1.entries()){
    console.log(key); //1、1
    console.log(value); //2、2 key和value相等
}

Map

同上面的Set类似,Map是一种类对象的数据结构,只有一点不同的是对象的key只能是String类型的,而Map的key可以是任意类型的.通过Map构造函数实例化Map对象的时候,只能传入数组参数,如果有多个元素,那么每个元素都只能以数组想的形式传入,否则无法识别元素.

let m2 = new Map([["name","stark"],[2,3],[4,6]]);

如实例代码,传入的参数只能是数组格式.实例的Map对象m2的3个元素["name","stark"],[2,3],[4,6],这些元素也只能是数组格式的,只是每个数组里面只有2个数组项,一个为map的key,另一个为map的value.如果不是以数组格式传入的,那么map就不能正确获取到这些元素,在获取这些值的时候就会为undefined.

let m2 = new Map([["name","stark"],{2:3},[4,6]]);
console.log(m2); //Map { 'name' => 'stark', undefined => undefined, 4 => 6 }

Map也可以通过set添加元素

let map = new Map();
let keyObj = {};
let keyFun = function(){};
let keyString = "A String";
map.set(keyString,"和键a string相关的值");

通过get取值

let map = new Map();
let keyFun = function(){};
map.set(keyFun,"和键keyFun相关的值");
console.log(map.get(keyFun)); //和键keyFun相关的值

通过size属性获取map的元素个数

let map = new Map();
let keyFun = function(){};
map.set(keyFun,"和键keyFun相关的值");
console.log(map.get(keyFun)); //和键keyFun相关的值
console.log(map.size); //1

Map的常用方法

1.清空元素

clear()移除map中所有的元素

let map = new Map();
let keyFun = function(){};
map.set(keyFun,"和键keyFun相关的值");
console.log(map.get(keyFun)); //和键keyFun相关的值
console.log(map.size); //1
map.clear();
console.log(map); //Map {}

2.添加元素

上面已经说过

3.获取元素

上面已经说过

4.移除元素

delete(key):如果map中存在该元素,返回true,如果不存在,则返回false

let map = new Map();
let keyFun = function(){};
map.set(keyFun,"和键keyFun相关的值");
console.log(map.delete(keyFun)); //true

5.判断map中是否含有某个key对应的值

has(key):判断map中是否有key对应的值,如果有,返回true,没有返回false

let map = new Map();
let keyFun = function(){};
map.set(keyFun,"和键keyFun相关的值");
console.log(map.has("name")); //false
console.log(map.has(keyFun)); //true

6.map元素遍历

forEach(callback,[,thisArg])

callback:回调函数,包括3个参数:

  • value:元素的值value
  • key:元素的键key
  • map:当前正在被遍历的对象

这个方法会返回一个多余的undefined,现在没有搞清楚原因呢.

let map = new Map();
map.set("name","Nicholas");
console.log(map);
console.log(map.forEach((value,key) => {
    console.log(key+ ": " + value); //name: Nicholas,undefined
}));

for …… of:map的这个遍历方法和Set的相同,就不再描述了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值