用ES5模拟实现ES6中的Set类

集合是由一组无序且唯一的项组成,ECMAScript2015(ES6)包括了Set类的实现,下面用ES5模拟实现ES6中的Set类

1.创建集合

我们用对象来实现Set类,当然也可以用数组,js对象一个键不能指向两个值,这保证了集合元素的唯一性。先初始化Set类

function Set() {
    var items = {};
}
1.1 has方法
this.has = function(value){
        return value in items;
    }

用js的in操作符验证给定值是否是items对象的属性,这个方法还有更好的一个实现,那就是用js对象都有的hasOwnProperty方法

this.has = function(value){
        return items.hasOwnProperty(value);
    }
1.2 add方法
this.add = function(value){
        if (!this.has(value)) {
            items[value] = value;
            return true;
        }
        return false;
    }

注:添加一个值时,把它同时作为键和值保存,这样有利于查找该值

1.2 remove和clear方法
this.remove = function(value){
        if (this.has(value)) {
            delete value;
            return true;
        }
        return false;
    },
    this.clear = function(){
        items={};
    }

 

1.3 size方法

size方法的实现可以使用一个length属性,每当调用add和remove方法时动态更新其值;

也可以使用js的Object类实现

this.size = function(){
        return Object.keys(items).length;
    }

最后一种方法是,手动统计items对象的属性数量

this.size = function(){
        var count = 0;
        for(var prop in items){
            if (items.hasOwnProperty(prop)) {
                ++count;
            }
        }
        return count;
    }
1.4 values方法

values方法提取items对象所有属性,以数组形式返回

this.values= function(){
        var values = [];
        for(var value in items){
            if (items.hasOwnProperty(value)) {
                values.push(value);
            }
        }
        return values;
    }

 

2.集合操作

2.1 并集

创建一个新集合代表两个集合的并集,分别变量两个集合的所有值,将他们添加到代表并集的集合中,最后返回并集。

this.union = function(otherSet){
        var unionSet = new Set();
        var values = this.values();
        for (var i = 0; i < values.length; i++) {
            unionSet.add(values[i]);
        }

        values = otherSet.values();
        for (var i = 0; i < values.length; i++) {
            unionSet.add(values[i]);
        }

        return unionSet;
    }

 

2.2 交集

创建一个新集合代表两个集合的交集,遍历一个集合的所有值,将另一个集合中同样也含有的值,添加到代表交集的集合中,最后返回交集。

this.intersection = function(otherSet){
        var intersection = new Set();
        var values = this.values();
        for (var i = 0; i < values.length; i++) {
            if (otherSet.has(values[i])) {
                intersection.add(values[i]);
            }
        }
        return intersection;
    }
2.3 差集

差集实现和交集类似,只不过是遍历一个集合的所有值,将另一个集合中不在这个集合中的值,添加到代表差集的集合中,最后返回差集。

this.difference = function(otherSet){
        var difference = new Set();
        var values = this.values();
        for (var i = 0; i < values.length; i++) {
            if (!otherSet.has(values[i])) {
                difference.add(values[i]);
            }
        }
        return difference;
    }
2.4 子集

判断调用subset方法的集合是不是otherSet的子集

this.subset = function(otherSet){
        var values = this.values();
        if (this.size() > otherSet.size()) {
            return false;
        }
        else{
            for (var i = 0; i < values.length; i++) {
                if (!otherSet.has(values[i])) {
                    return false;
                }
            }
            return true;
        }
    }

下面给出完整实现的Set类

function Set() {
    var items = {};
    // this.has = function(value){
    //     return value in items;
    // }
    this.has = function(value){
        return items.hasOwnProperty(value);
    },
    this.add = function(value){
        if (!this.has(value)) {
            items[value] = value;
            return true;
        }
        return false;
    },
    this.remove = function(value){
        if (this.has(value)) {
            delete value;
            return true;
        }
        return false;
    },
    this.clear = function(){
        items={};
    },
    this.size = function(){
        var count = 0;
        for(var prop in items){
            if (items.hasOwnProperty(prop)) {
                ++count;
            }
        }
        return count;
    },
    this.values= function(){
        var values = [];
        for(var value in items){
            if (items.hasOwnProperty(value)) {
                values.push(value);
            }
        }
        return values;
    },
    this.union = function(otherSet){
        var unionSet = new Set();
        var values = this.values();
        for (var i = 0; i < values.length; i++) {
            unionSet.add(values[i]);
        }

        values = otherSet.values();
        for (var i = 0; i < values.length; i++) {
            unionSet.add(values[i]);
        }

        return unionSet;
    },
    this.intersection = function(otherSet){
        var intersection = new Set();
        var values = this.values();
        for (var i = 0; i < values.length; i++) {
            if (otherSet.has(values[i])) {
                intersection.add(values[i]);
            }
        }
        return intersection;
    },
    this.difference = function(otherSet){
        var difference = new Set();
        var values = this.values();
        for (var i = 0; i < values.length; i++) {
            if (!otherSet.has(values[i])) {
                difference.add(values[i]);
            }
        }
        return difference;
    },
    this.subset = function(otherSet){
        var values = this.values();
        if (this.size() > otherSet.size()) {
            return false;
        }
        else{
            for (var i = 0; i < values.length; i++) {
                if (!otherSet.has(values[i])) {
                    return false;
                }
            }
            return true;
        }
    }
}

 

转载于:https://www.cnblogs.com/Cathamerst/p/7220591.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值