Set、Map集合及其源码

1 篇文章 0 订阅

 

Set集合

定义:

是一种数据的存储结构,不同的场景运用不同的集合存储数据。存放的数据必须为可迭代对象。

作用:

用于存放不重复的数据。

原型方法:

方法和属性含义
add(value)添加某个值,返回Set结构本身
delete(value)删除某个值,返回一个布尔值,表示删除是否成功
has(value)返回一个布尔值,表示该值是否为Set的成员
clear()清除所有成员,没有返回值
keys()返回键名的遍历器
values()返回键值的遍历器
entries()返回键值对的遍历器(for in)
forEach()使用回调函数遍历每个成员
size获取成员个数

实例应用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        let s=new Set([1,2,2,3,3,4,5,5]);
        console.log(s);//[1,2,3,4,5]

        s.add(10)
        s.add(20)
        console.log(s);//[1,2,3,4,5,10,20]
        

        console.log(s.delete(1));//[2,3,4,5,10,20]
        

        console.log( s.has(2));//true
        
        console.log(s.keys());//{2, 3, 4, 5, 10, …}
        console.log(s.values());//{2, 3, 4, 5, 10, …}
        console.log(s.entries());//{2 => 2, 3 => 3, 4 => 4, 5 => 5, 10 => 10, …}

        s.clear()
        console.log(s);//{}
       

    </script>
</body>
</html>

简单练习

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        const arr1 = [12,34,55,33,11,33,5,12]
        const arr2 = [55,34,11,78,10,19,88,88,99,99]
        // 使用set集合完成两个数组的交集、并集和差集

        const cross = [...new Set(arr1)].filter(item => arr2.indexOf(item) >= 0)
        console.log(cross)


        const result = [...new Set([...arr1,...arr2])]
        console.log(result)

        console.log(result.filter(item => cross.indexOf(item) < 0))

    </script>
</body>
</html>

Set源码

class MySet{
    constructor(iterator = []){
        // 传递的内容必须是一个可迭代对象
        if(typeof iterator[Symbol.iterator] !== "function"){
            throw new TypeError(`您所提供的${iterator}不是一个可迭代对象`)
        }
        this._datas = [];
        for(const item of iterator){
            this.add(item)
        }
    }
    get size(){
        return this._datas.length
    }
    add(data){
        if(!this.has(data)){
            this._datas.push(data)
        }
    }
    has(data){
        for(const item of this._datas){
            if(this.isEqual(item,data)){
                return true
            }
        }
        return false
    }
    delete(data){
        for(let i = 0 ;i<this._datas.length;i++){
            const element = this._datas[i];
            if(this.isEqual(element,data)){
                this._datas.splice(i,1)
                return true
            }
        }
    }
    clear(){
        this._datas.length = 0
    }
    *[Symbol.iterator](){
        for(const item of this._datas){
            yield item;
        }
    }
    forEach(callback){
        for(const item of this._datas){
            callback(item,item,this)
        }
    }
    // 判断两个数据是否相等
    isEqual(data1,data2){
        if(data1 == 0 && data2 == 0){
            return true
        }
        return Object.is(data1,data2)
    }
}

map集合

定义:

类似于对象,里面保存的数据是键值对的形式但是“键”的范围不限于字符串,各种类型的值( 包括对象)都可以当作键和Object的区别是Map的键名可以为值参数必须是数组,数据项也要为数组

作用:

键名不重复,以键值对的形式存储。

原型方法:

方法和属性含义
set(key, value)set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如 果key已经有值,则键值会被更新,否则就新生成该键
delete(value)删除某个值,返回一个布尔值,表示删除是否成功
has(value)返回一个布尔值,表示该值是否为Set的成员
clear()清除所有成员,没有返回值
keys()返回键名的遍历器
values()返回键值的遍历器
entries()返回键值对的遍历器(for in)
forEach()使用回调函数遍历每个成员
size获取成员个数
get(key)get方法读取key对应的键值,如果找不到key,返回undefined

实例应用

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 数组中的子数组里面只能有两项,第一项代表键名,第二项代表键值
        const map = new Map([
            ["a", 1],
            [1, 2],
            [true, 3]
        ])
        console.log(map)
        // 添加属性
        map.set("b", 4)
        // 取值
        console.log(map.get(true))
        // 取长度
        console.log(map.size)

        const map = new Map()
        map.set({}, 1)
        map.set({}, 2)
        let obj = {};
        map.set(obj, 1)
        map.set(obj, 2)
        console.log(map.size)


        for (const iterator of map) {
            console.log(iterator)
            console.log(iterator[0], iterator[1]) //一般不会这么写
        }
        //for of 遍历可迭代对象
        for (const [key, value] of map) {
            console.log(key, value)
        }

        console.log(map);
        map.forEach((value, key, map) => {
            console.log(value, key, map)
            // value 值
            // key 键
            // map对象本身
        })
    </script>
</body>

</html>

map源码

class MyMap{
    constructor(iterator = []){
        if(typeof iterator[Symbol.iterator] !== "function"){
            throw TypeError(`您所提供的${iterator}不是一个可迭代对象`)
        }
        this._datas = [];//
        for (const item of iterator) {
            if(typeof item[Symbol.iterator] !== "function"){
                throw TypeError(`您所提供的${item}不是一个可迭代对象`)
            }
            // const key = item[0];
            // const value = item[1];
            const iter = item[Symbol.iterator]();
            const key = iter.next().value;//["a",1]
            const value = iter.next().value;
            this.set(key,value)
        }
    }
    set(key,value){
        const obj = this._getObj(key);
        if(obj){//如果key值相同则覆盖值
            obj.value = value
        }else{
            this._datas.push({
                key,
                value
            })
        }
    }
    get(key){
        const obj = this._getObj(key);
        if(obj){
            return obj.value
        }
        return undefined;
    }
    get size(){
        return this._datas.length;
    }
    delete(key){
        for(let i = 0 ;i<this._datas.length;i++){
            const element = this._datas[i];
            if(this.isEqual(element.key,key)){
                this._datas.splice(i,1)
                return true
            }
        }
        return false;
    }
    clear(){
        this._datas.length = 0
    }
    has(key){
        return this._getObj(key) !== undefined;
    }
    *[Symbol.iterator](){
        for(const item of this._datas){
            yield [item.key,item.value]
        }
    }
    forEach(callback){
        for (const item of this._datas) {
            callback(item.value,item.key,this)
        }
    }
    _getObj(key){
        for(const item of this._datas){
            if(this.isEqual(item.key,key)){
                return item
            }
        }
    }
    isEqual(data1,data2){
        if(data1 === 0 && data2 === 0){
            return true;
        }
        return Object.is(data1,data2)
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值