set 集合
一直以来,JS只能使用数组和对象来保存多个数据,缺乏像其他语言那样拥有丰富的集合类型。因此,ES6新增了两种集合类型(set 和 map),用于在不同的场景中发挥作用。
如何创建set集合(set用于存放不重复的数据)
new Set(); //创建一个没有任何内容的set集合 new Set(iterable); //创建一个具有初始内容的set集合,内容来自于可迭代对象每一次迭代的结果
如何对set集合进行后续操作
-
add(数据): 添加一个数据到set集合末尾,如果数据已存在,则不进行任何操作
-
set使用Object.is的方式判断两个数据是否相同,但是,针对+0和-0,set认为是相等
-
-
has(数据): 判断set中是否存在对应的数据
-
delete(数据):删除匹配的数据,返回是否删除成功
-
clear():清空整个set集合
-
size: 获取set集合中的元素数量,只读属性,无法重新赋值
如何与数组进行相互转换
const s = new Set([x,x,x,x,x]);
// set本身也是一个可迭代对象,每次迭代的结果就是每一项的值
const arr = [...s];
如何遍历
1). 使用for-of循环
2). 使用set中的实例方法forEach
注意:set集合中不存在下标,因此forEach中的回调的第二个参数和第一个参数是一致的,均表示set中的每一项
创建一个构造器
constructor(iterator = []) {
if (typeof iterator[Symbol.iterator] !== "function") {
throw new TypeError(`你提供的${iterator}不是一个可迭代对象`)
}
this._data = []
for (const item of iterator) {
this.add(item)
}
}
添加一个元素
add(data) {
if (!this.has(data)) {
this._data.push(data)
}
}
获取set集合中的元素数量(size是一个访问器属性)
get size() {
return this._data.length
}
判断是set集合否存在一个元素
has(data) {
for (let index = 0; index < this._data.length; index++) {
let temp = this._data[index]
if (this.isEqual(data, temp)) {
return true
}
}
return false
}
//辅助函数,判断两个元素是否相等
isEqual(data1, data2) {
if (data1 === 0 && data2 === 0) return true
return Object.is(data1, data2)
}
删除与清空数据
delete(data) {
for (let index = 0; index < this._data.length; index++) {
let temp = this._data[index]
if (this.isEqual(temp, data)) {
this._data.splice(index, 1)
return true
}
}
return false
}
clear() {
this._data.length = 0
}
创建迭代器
*[Symbol.iterator]() {
for (const element of this._data) {
yield element
}
}
实现forEach
forEach(callback) {
for (const element of this._data) {
callback(element, element, this)
}
}
完整代码如下:
class MySet {
constructor(iterator = []) {
if (typeof iterator[Symbol.iterator] !== "function") {
throw new TypeError(`你提供的${iterator}不是一个可迭代对象`)
}
this._data = []
for (const item of iterator) {
this.add(item)
}
}
//增加一个元素
add(data) {
if (!this.has(data)) {
this._data.push(data)
}
}
//判断是否存在一个元素
has(data) {
for (let index = 0; index < this._data.length; index++) {
let temp = this._data[index]
if (this.isEqual(data, temp)) {
return true
}
}
return false
}
//判断两个元素是否相等
isEqual(data1, data2) {
if (data1 === 0 && data2 === 0) return true
return Object.is(data1, data2)
}
//删除数据
delete(data) {
for (let index = 0; index < this._data.length; index++) {
let temp = this._data[index]
if (this.isEqual(temp, data)) {
this._data.splice(index, 1)
return true
}
}
return false
}
//清空
clear() {
this._data.length = 0
}
//迭代器创建
*[Symbol.iterator]() {
for (const element of this._data) {
yield element
}
}
//forEach
forEach(callback) {
for (const element of this._data) {
callback(element, element, this)
}
}
}