用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;
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM