JavaScript数据结构与算法之 "集合"

  • 昨天实现的集合有一些bug,这次重写了代码。

集合数据结构

  • 集合是由一组无序且唯一(即不重复)的项组成
  • 空集:空集是不包含任何元素的集合
  • 可以把集合想象成一个既没有重复元素,也没有顺序概念的数组
  • 集合在计算机领域中的运用
    • 集合在计算机科学中的主要应用之一是数据库
    • 集合被用于数据库查询的设计和处理
    • 当我们执行数据库的查询语句时,使用的就是集合运算,并且数据库也会返回一个数据集合
  • 集合的运算
    • 并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合
    • 交集:对于给定的两个集合,返回一个包含两个集合中共有的元素的新集合
    • 差集:对于给定的两个集合,返回一个包含所有存在于第一个集合但不存在于第二个集合中的元素组成的新集合
    • 子集:验证一个给定的集合中的元素是否都存在于另一个集合中

使用对象实现集合

  • 将参数转换为字符串

    /*将传入的参数转换为字符串*/
    const toStr = (param) => {
        if (param === null) {
            return 'NULL';
        } else if (param === undefined) {
            return 'UNDEFINED';
        } else if (typeof param === 'number' || param instanceof Number) {
            return `${param}`;
        } else if (typeof param === 'string' || param instanceof String) {
            return `${param}`;
        } else if (typeof param === 'symbol') {
            return param;
        } else {
            return JSON.stringify(param);
        }
    };
    
  • 方法

    • add(element):向集合中添加一个新元素
    • delete(element):从集合中删除一个元素
    • has(element):判断元素是否存在于集合中,存在返回true,不存在返回false
    • clear():删除集合中所有的元素
    • size():返回集合中所有元素的数量。它与数组的length属性类似
    • values():返回由集合中所有元素构成的数组
    • union(otherSet):返回当前集合和另一个集合的并集
    • intersection(otherSet):返回当前集合和另一个集合的交集
    • difference(otherSet):返回当前集合和另一个集合的差集
    • isSubsetOf(otherSet):判断当前集合是否是另一个集合的子集
  • 代码

    /*创建集合的类*/
    class Set {
        constructor() {
            this.items = {};  // 存储集合元素的对象
        }
    
        // add(element):向集合中添加一个新元素
        add(element) {
            if (this.has(element)) { // element在集合中
                return false;
            }
    
            const key = toStr(element);
            this.items[key] = element;
            return true;
        }
    
        // delete(element):从集合中删除一个元素
        delete(element) {
            if (this.has(element)) { // element在集合中
                const key = toStr(element);
                delete this.items[key];
                return true;
            }
    
            return false;
        }
    
        // has(element):判断元素是否存在于集合中,存在返回true,不存在返回false
        has(element) {
            const key = toStr(element);
            return Object.prototype.hasOwnProperty.call(this.items, key);
        }
    
        // clear():删除集合中所有的元素
        clear() {
            this.items = {};
        }
    
        // size():返回集合中所有元素的数量。它与数组的length属性类似
        size() {
            return Object.keys(this.items).length;
        }
    
        // values():返回由集合中所有元素构成的数组
        values() {
            return Object.values(this.items);
        }
    
        // union(otherSet):返回当前集合和另一个集合的并集
        union(otherSet) {
            const newSet = new Set();
    
            this.values()
                .concat(otherSet.values())
                .forEach((v) => newSet.add(v));
    
            return newSet;
        }
    
        // intersection(otherSet):返回当前集合和另一个集合的交集
        intersection(otherSet) {
            const newSet = new Set();
    
            // 找到元素最多的集合
            let bigSet = this;
            let smallSet = otherSet;
    
            if (bigSet.values().length < smallSet.values().length) { // 如果bigSet中的元素数量小于smallSet中元素的数量
                bigSet = otherSet;
                smallSet = this;
            }
    
            smallSet.values()
                .filter((v) => bigSet.has(v))
                .forEach((v) => newSet.add(v));
    
            return newSet;
        }
    
        // difference(otherSet):返回当前集合和另一个集合的差集
        difference(otherSet) {
            const newSet = new Set();
    
            this.values()
                .filter((v) => !otherSet.has(v))
                .forEach((v) => newSet.add(v));
    
            return newSet;
        }
    
        // isSubsetOf(otherSet):判断当前集合是否是另一个集合的子集
        isSubsetOf(otherSet) {
            if (this.size() > otherSet.size()) { //如果当前集合中的元素大于另一个集合中的元素
                return false;
            }
    
            return this.values().every((v) => otherSet.has(v));
        }
    
    }
    
  • 集合的使用

    const set1 = new Set();
    set1.add(1);
    set1.add({});
    set1.add(undefined);
    set1.add(undefined);
    set1.add(null);
    set1.add(null);
    set1.add({a:'李四'});
    
    const set2 = new Set();
    set2.add(1);
    set2.add(2);
    set2.add([1]);
    set2.add(['a','b','c']);
    set2.add(undefined);
    
    console.log(set1.values());
    console.log(set1.union(set2).values());
    console.log(set1.intersection(set2).values());
    console.log(set1.difference(set2).values());
    console.log(set1.isSubsetOf(set2));
    
    // 结果
    // [ 1, {}, undefined, null, { a: '李四' } ]
    // [ 1, 2, {}, undefined, null, { a: '李四' }, [ 1 ], [ 'a', 'b', 'c' ] ]
    // [ 1, undefined ]
    // [ {}, null, { a: '李四' } ]
    // false
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值