JavaScript模拟集合

321 阅读3分钟

1 集合

集合:由一组无序且值不重复的元素组成

特点:

  • 1.元素无序
  • 2.元素不重复

实现代码:

    //使用对象实现集合
    function Set(){
        //定义一个空对象,存储集合中的元素
        this.items = {};

        //向集合中添加一个新的元素
        Set.prototype.add = function ( value ) {
            //判断元素是否已经存在集合中
            if(!this.has(value)){
                //集合中没有该元素,就进行添加, 键和值都是元素,方便查找
                this.items[value] = value;
                return true;
            }else{
                //已经存在,不添加,返回false
                return false;
            }

        }
        //从集合中移除元素
        Set.prototype.remove = function ( value ) {
            //判断要移除的元素是否在集合中
            if(this.has(value)){
                //在集合中,直接移除,delete关键字用于删除对象的某个属性
                delete this.items[value];
                return true;
            }else{
                //集合中没有要移除的元素,不做移除操作,放回false
                return false;
            }
        }
        //判断指定值是否在集合中,存在返回true,不存在,返回false
        Set.prototype.has = function ( value ) {
            //hasOwnProperty对象自身属性中是否具有指定的属性
            return this.items.hasOwnProperty(value);
        }
        //移除集合中的所有元素
        Set.prototype.clear = function (  ) {
            this.items = {};
        }
        //返回集合中元素的数量
        Set.prototype.size = function (  ) {
            //获取指定对象所有属性的数组,有兼容问题
            // return Object.keys(this.items).length;
            let count = 0;
            //取出集合中元素,计算个数
            for(let key in this.items){
                //使用hasOwnProperty判断,避免将原型中元素也计算进去,进行排除
                if(this.items.hasOwnProperty(key)){
                    count++;
                }
            }
            return count;
        }
        //返回集合中所有元素的值的数组
        Set.prototype.values = function (  ) {
            let arr = [];
            for(var key in this.items){
                if(this.items.hasOwnProperty(key)){
                    arr.push(this.items[key]);
                }
            }
            return arr;
        }

        //并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合
        //分别将两个集合的值转换为两个数组,遍历数组,将值存储到新集合中
        Set.prototype.union = function ( otherSet ) {
            let newSet = new Set();
            let selfValues = this.values();
            //遍历,将自己所有元素添加到新集合中
            for ( let i = 0 ;i<selfValues.length;i++ ) {
                newSet.add(selfValues[i]);
            }
            let otherValues = otherSet.values();
            for ( var i = 0 ;i<otherValues.length;i++ ) {
                newSet.add(otherValues[i]);
            }
            return newSet;
        }
        //交集:元素存在同时存在于集合A和集合B中
        Set.prototype.intersection = function ( otherSet ) {
            let newSet = new Set();
            let selfValues = this.values();
            for ( let i = 0 ;i<selfValues.length;i++ ) {
                //判断集合A中元素是否存在于集合B中,如果在,就存储到新集合中
                if(otherSet.has(selfValues[i])){
                    newSet.add(selfValues[i]);
                }

            }
            return newSet;
        }
        //差集:元素存在集合A中,但是不存在集合B中
        Set.prototype.difference = function ( otherSet ) {
            let newSet = new Set();
            let selfValues = this.values();
            for ( let i = 0 ;i<selfValues.length;i++ ) {
                //判断集合A中元素是否存在于集合B中,如果不在,就存储到新集合中
                if(!otherSet.has(selfValues[i])){
                    newSet.add(selfValues[i]);
                }

            }
            return newSet;
        }
        //子集:集合A的个数小于集合B,并且集合A的每一个元素存在集合B中
        //判断集合A是否是集合B的子集
        Set.prototype.isSubsetOf = function ( otherSet ) {

            if(this.size()>otherSet.size()){
                return false;
            }
            let selfValues = this.values();
            for ( let i = 0 ;i<selfValues.length;i++ ) {
                //判断集合A中元素是否存在于集合B中,如果不在,就存储到新集合中
                if(!otherSet.has(selfValues[i])){
                    //只有集合A中有一个元素不在集合B中,就返回false
                   return false;
                }
            }
            return true;
        }
    }

验证:

  //测试集合
    let mySet = new Set();
    mySet.add(1);
    console.log ( mySet.values () );//打印数组[1]
    console.log ( mySet.has ( 1 ) );//true
    console.log ( mySet.size () );//
    mySet.add(2);
    console.log ( mySet.values () );//打印数组[1, 2]
    console.log ( mySet.has ( 2 ) );//true
    
    mySet.remove(1);
    console.log ( mySet.values () );//打印数组[2]
    
    mySet.remove(2);
    console.log ( mySet.values () );//打印数组[]

    //测试并集,交集,差集,子集
    let setA = new Set();
    let setB = new Set();

    setA.add(1);
    setA.add(2);
    setA.add(3);
    setA.add(4);

    setB.add(3);
    setB.add(4);
    setB.add(5);
    setB.add(6);

    //获取setA和setB的并集
    let unionAB = setA.union(setB);
    console.log ( unionAB.values () );//输出[1, 2, 3, 4, 5, 6]

    //获取setA和setB的交集
    let intersectionAB = setA.intersection(setB);
    console.log ( intersectionAB.values () );//输出[3,4]

    //获取setA和setB的差集,存在于setA中,且不存在于setB中的元素
    let differenceAB = setA.difference(setB);
    console.log ( differenceAB.values () );//[1,2]

    //判断setA是不是setB的子集
    console.log ( setA.isSubsetOf ( setB ) );//false

    let setC = new Set();
    let setD = new Set();
    setC.add(100);
    setC.add(200);
    setC.add(300);

    setD.add(100);
    setD.add(200);
    setD.add(300);
    setD.add(400);
    setD.add(500);

    console.log ( setC.isSubsetOf ( setD ) );//true