JavaScript中的Set

566 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Set基本用法

在ES6里面新增了一种 Set 新集合类型,就像String、Number类型,它本身就是一个构造函数,用来生成 Set 类型的数据结构;所以我们就可以这样使用new关键字来创建一个新的空集合,在Set构造函数里面我们需要传入一个可迭代对象,一般数组比较常见(当然可以不传,不过new出来的对象就没啥意义)

const s=new Set([1,1,2,2,3,3,4,4])//我们传入一个数组来初始化
console.log(s)//打印

然后我们就可以看到下面结果:

QQ图片20220726180510.png

我们可以看到这个集合的大小为4,并且它自动的将重复的值去重了。并且看起来是不是有点像数组,但是它并没有键值对。由此我们可以知道Set类似于数组,其成员的值都是唯一的,没有重复的值。 所以利用这个特性就可以利用它来去重。那么如果我们想得到一个数组呢?请看下面

const s=new Set([1,1,2,2,3,3,4,4])
console.log([...s])//利用解构,将元素全部取出,然后放到一个数组里面来

QQ图片20220726183117.png

如果要获取集合里面的元素,当然也要先解构,再访问

const s=new Set([1,1,2,2,3,3,4,4])
console.log([...s][1])//将其解构为数组,再访问下标为1的元素

结果:

QQ图片20220726193450.png

当然我们也可以将一个字符串去重

const s=new Set('aaabbbccc')
console.log([...s]);

QQ图片20220726183449.png

Set属性的实例以及方法

在初始化之后,可以使用add()来增加值,使用has()来查询值,delete()来删除元素,以及用size来获取元素的数量。

s.add('matt')
 .add('tom')
console.log(s);//{ 'bruce', 'jack', 'lucy', 'matt', 'tom' }
console.log(s.size);//通过size获取元素数量,值为5

//查询值
console.log(s.has('bruce'));//true
console.log(s.size);//5


//删除值,delete()返回布尔值,表示集合中是否存在要删除的值
console.log(s.delete('jack'));//true
console.log(s.size);//4

结果如下:

QQ图片20220726193116.png

遍历

Set有四种遍历方法

  • Set.prototype.keys() :返回键名的遍历器
  • Set.prototype.values() :返回键值的遍历器
  • Set.prototype.entries():返回键值对的遍历器
  • Set.prototype.forEach():使用回调函数遍历每个成员

keys()方法、values()方法、entries()方法返回的都是遍历器对象,但是因为Set没有键名,只有键值,所以keys()与values()结果是一样的;但是entries()方法返回的是键---值,并且每次返回的都是数组,这两个键与值是相等的。Set的键名就是键值。

let s = new Set(['a', 'b', 'c', 'd'])

for (let item of s.keys()) {
    console.log(item);// a b c d
}

for (let item of s.values()) {
    console.log(item);// a b c d
}

for (let item of s.entries()) {
    console.log(item);
}
// [ 'a', 'a' ]
// [ 'b', 'b' ]
// [ 'c', 'c' ]
// [ 'd', 'd' ]

也可以用for of遍历:

let s = new Set(['a', 'b', 'c', 'd'])

for(let item of s.keys()){
    console.log(item);
}
//a
//b
//c
//d

那么为什么Set可以被遍历呢?下面我们来看看这个

QQ图片20220726195723.png

我们打印出keys(),发现里面有个迭代器,所以可以被遍历。

Set的遍历应用

1.求交集 filter()数组的过滤器,过滤出满足条件的

let arr=[1,2,3,5]

let fArr=arr.filter((item,index)=>{  //数组的过滤器,过滤出满足条件的
    return item>2
})
console.log(fArr);//[ 3, 5 ]

知道这个我们就可以求Set的交集

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

let intersect=[...a].filter((x)=>{//要先解构成数组才能使用filter()
    return b.has(x)
})
console.log(intersect);
//[ 2, 3 ]

2.求并集

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

let union=new Set([...a,...b])
console.log(union);

WeakSet

WeakSet与Set类似,但是WeakSet的成员只能是对象

const ws=new WeakSet()
// ws.add(1)//不能直接添加原始值,否则就会报错 
ws.add([1,2])//可以接受一个数组或者一个类似数组的,数组里面的会成为ws的成员
console.log(ws);//ws:{[1,2]}

QQ图片20220726202530.png

WeakSet有add() delete() has()方法;相较于Set,WeakSet的成员只能是对象,而不能是其他类型的值。

而WeakSet对象里面的对象都是弱引用,就是说如果某些东西存储在传统的object里面,一旦这个东西不需要再使用了,这个东西还在内存中存在一段时间直到垃圾回收器将其回收;而如果将东西存在WeakSet里面,当这个东西不需要使用了就会立马消失,而不是等到垃圾回收器来回收。