set和map数据结构之set

set和map数据结构之set

基本用法

1、数据结构set本身是一个构造函数,用于生成Set数据结构。它类似于数组,但是成员的值都是唯一的,没有重复的值。

const s = new Set();
[1,2,3,5,2,3,5].forEach(x => s.add(x));
for (let i of s) {
console.log(i);
}
// 1,2,3,5

以上的代码通过add()方法向Set结构加入成员,结果显示Set结构不会添加重复的值。
2、Set函数可以接受一个数组或者类数组作为参数,用于初始化。

//例一
const set = new Set([1,2,3,4,4]);
[...set]
// [1,2,3,4]

// 例二
const set2 = new Set([1,2,3,4,4,4,4]);
set3.size //4

// 例三
// document.querySelectAll('div') 得到的是一个类数组
const set3 = new Set(document.querySelectorAll('div'));
set3.size  

// 类似于
const set3 = new Set();
document.querySelectorAll('div').forEach(div => set3.add(div));
set3.size 

3、Set数组去重

// 数组去重
[...new Set(array)]
// 也可以用于字符串里重复的字符去重
[...new Set('aaassdd')].join('')
// 'a s d'

向Set加入值的时候,不会发生类型转换,所以2和‘2’是两个不同的值。Set内部判段两个值是否不同,使用的算法叫做”Same-value-zero equality“,类似于全等(===),但还是有区别,向Set加入值时认为NaN等于自身,当向Set里添加两次NaN时,只会有一个,而全等则认为NaN不等于自身。

let set = new Set();
let a = NaN;
let b = NaN;
set.add(a);
set.add(b);
// Set {NaN} 在Set内部两个NaN时相等的

但在Set中,两个空对象是不相等的。

let set = new Set();
set.add({});
set.size // 1

set.add({});
set.size // 2

Set实例的属性和方法

1、Set结构的实例有以下属性。
Set.prototype.constructor:构造函数,默认就是Set函数。
Set.prototype.size:返回Set实例的成员总数。

2、Set实例的方法分为两大类:操作方法 和遍历方法。
操作方法:
let set = new Set();
set.add(value): 添加某个值,返回Set结构本身。
set.delete(value):删除某个值,返回一个布尔值,表示是否删除成功。
set.has(value):表示该值是否为Set的成员。
Set.clear():清除所有成员,没有返回值。

// 例 
let s = new Set();
s.add(1).add(2).add(2);
s.size // 2
s.has(1) //true
s.has(2) // true
s.has(3) //false

s.delete(1);
s.has(1); //false

对比:在判断是否包含一个键上面,Object 结构和Set结构的写法不同。

// Object的写法
const properties = {
'width'1'height' : 2,
};
if(properties[someone]) {
// do something
}

// Set的写法 
const properties = new Set();
properties.add('width');
properties.add('height');
if(properties.has(someName)) {
// do something

3、Array.from 方法可以将Set结构转化为数组。(数组去重的另一种方法)

const items = new Set([1,2,3,4,4,5]);
const array = Array.from(items)
// [1,2,3,4,5]
// function dedupe(array) {
return Array.from(new Set(array));
}
dedupe([1,2,1,2]) // [1,2]

遍历操作

1、Set 结构的实例有四个遍历方法,可以用于遍历成员。
Set.prototype.keys():返回键名;
Set.prototype.values():返回键值;
Set.prototype.entries():返回键值对;
Set.prototype.forEach():使用回调函数遍历每个成员。
2、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
for(let item of set.entries()) {
console.log(item);
}
// ["red","red"]
// ["green","green"]
// ["blue","blue"]

3、Set结构的实例默认可遍历,它的默认遍历器就是它的values方法。

	Set.prototype[symbol.iterator] === Set.prottype.values  // true
	// 这意味着可以省略values方法,直接用for...of遍历循环Set.
	let set = new Set(['red','green','blue']);
	for(let x of set) {
	console.log(x);
	}
	// red
	// green
	// blue

Set结构的实例与数组一样,也有forEach方法,用于对每个成员执行某种操作,没有返回值。

let set = new Set([1,4,9]);
set.forEach((value,key) => console.log(key + ':' + value))
// 1:1
// 4:4
// 9:9

上面代码说明,forEach方法的参数就是一个处理函数。该函数的参数参与数组的forEach一致,依次为键值,键名,集合本身。这里需要注意的是Set结构的键名就是键值,因此第一个参数与第二个参数的值永远都是一样的。
另外,forEach方法还可以有第二个参数,表示绑定处理函数内部的this对象。

遍历的应用

扩展运算符(…) 内部使用for…of循环,所以也可以用于Set结构。

let set = new Set(['res','green','blue']);
let arr = [...set];
// ['red','green','blue']

扩展运算符和Set结构相结合,就可以去除数组的重复成员。

let arr = [2,3,4,5,2,3,4]
let unique = [...new Set(arr)];
// [2,3,4]

数组的map和filter方法也可以间接用于Set.

let set = new Set([1,2,3]);
set = new Set([...set].map(x => x *2));
// 返回Set结构:{2,4,6}

let set = new Set({1,2,3,4,5]);
set = new Set([...set].filter(x => (x % 2) == 0));
//返回Set结构:{2,4}

因此使用Set可以很容易的使用并集,交集,和差集。

let a = new Set([1,2,3]);
let b = new Set([2,3,6]);

// 并集
let union = new Set([...a,...b]);
// Set {1,2,3,4,5,6}

//交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2,3}

//差集(此处为a相对于b的差集)
let difference = new Set([...a].filter(x => !b.has(x)));
// set {1}

如果想在遍历操作中,同步改变原来的Set结构,目前没有直接的方法,但有两种变通方法。一种是利用原Set结构映射出一个新的结构,然后赋值给原来的Set结构;另一种是利用Array,from方法。

// 方法一
let set = new Set([1,2,3]);
set = new Set([...set].map(val => val *2 ));
// {2,4,6}

// 方法二
let set = new Set([1,2,3]);
set = new Set(Array.form(set,val => val *2));
// {2,4,6}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值