手写Set集合【JavaScript】

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)

        }

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值