您现在的位置:首页 >> 前端 >> 内容

集合

时间:2016/12/6 9:33:00 点击:

  核心提示: 集合是由一组无序且唯一(即不能重复)的项组成的。这个数据结构使用了与有限集合相同的概念,但应用于计算机科学的数据结构中。1,创建一个集合以下是set类的骨架:function Set(){var i...

集合是由一组无序且唯一(即不能重复)的项组成的。这个数据结构使用了与有限集合相同的概念,但应用于计算机科学的数据结构中。

1,创建一个集合

以下是set类的骨架:

function Set(){
    var items = {};
}

这里有一个非常重要的细节,我们使用对象而不是数组来表示集合(items),当然也可以用数组来实现。JS的对象不允许一个键指向两个不同的属性,也保证了集合里的元素都是唯一的。

接下来,需要声明一些集合可用的方法(我们会尝试模拟与ECMAScript6实现相同的Set类)。

add(value):向集合添加一个新的项。 remove(value):从集合移除一个值。 has(value):如果值在集合中,返回true,否则返回false。 clear():移除集合中的所有项。 size():返回集合中包含元素的数量。与数组的length属性类似。 values():返回一个包含集合中所有值的数组。

1,1,has(value)方法

首先要实现的是has(value)方法。这是因为它会被add、remove等其他方法调用。下面看看它的实现:

this.has = function(value){
    return value in items;
}

既然我们使用对象来存储集合的值,就可以用JavaScript的in操作符来验证给定的值是否是items对象的属性。

但这个方法还有更好的实现方式,如下:

this.has = function(value){
    return itmes.hasOwnProperty(value);
}

所有javascript对象都有hasOwnProperty方法。这个方法返回一个表明对象是否具有特定属性的布尔值。

1.2,add方法

实现add方法:

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

对于给定的value,可以检查它是否存在于集合中。如果不存在,就把value添加到集合中,返回true,表示添加了这个值。如果集合中已经存在这个值,就返回false,表示没有添加它。

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

1.3,remove和clear方法

下面要实现remove方法:

this.remove = function(value){
    if(this.has(value)){
        delete items[value];
        return true;
    }
    return false;
}

在remove方法中,我们会验证给定的value中是否存在于集合中。如果存在,那么就移除value,返回true;否则返回false。

既然用对象来存储集合的items对象,就可以简单地使用delete操作符从items对象中移除属性。

使用Set类的示例代码如下:

var set = new Set();
set.add(1);
set.add(2);

如果想移除集合中的所有值,可以用clear方法:

this.clear = function(){
    items = {};
}

要重置items对象,需要做的只是把一个空对象重新赋值给它。我们也可以迭代集合,用remove方法依次移除所有的值,但既然有更简单的方法,那样做就显得太麻烦了。

1.4,size方法

下一个要实现的是size方法(返回集合中有多少项)。这个方法有三种实现方式。
第一种方法是使用一个length变量,每当使用add或者remove方法时控制它,就像链表类一样。

第二种方法是使用js内建的Object类的一个内建函数(ECMAScript5以上版本):

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

JS的Object类有一个keys方法,它返回一个包含给定对象所有属性的数组。在这种情况下,可以使用这个数组的length属性来返回items对象的属性个数。只能在IE9以上版本和其他现代浏览器上使用。

第三种方法是手动提取items对象的每一个属性,记录属性的个数并返回这个数字。这个方法可以在任何浏览器上使用,和之前的代码是等价的:

this.sizeLegacy = function(){
    var count = 0;
    for(var prop in items){
        if(items.hasOwnProperty(prop))
        ++count;
    }
    return count;
}

遍历items对象的所有属性,检查他们是否是对象自身的属性。如果是,就递增count变量的值,最后在方法结束时返回这个数字。

1.5,values方法

values方法也应用了相同的逻辑,提取items对象的所有属性,以数组的形式返回:

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

以上代码只能在IE9及其他现代浏览器上使用。
如果想让代码在任何浏览器上使用,可以用与之前代码等价的下面这段代码:

this.valuesLegacy = function(){
    var keys = [];
    for(var key in items){
        keys.push(key);
    }
    return keys;
}

遍历items对象的所有属性,把他们添加到一个数组中,然后返回这个数组。

1.6,使用Set类

现在数据结构已经完成了,看看如何使用它吧。

var set = new Set();

set.add(1);
console.log(set.values());         //['1']
console.log(set.has(1));          //true
console.log(set.size());           //1

set.add(2);
console.log(set.values());           //['1','2']
console.log(set.has(2));             //true
console.log(set.size());            //2

set.remove(1);
console.log(set.values());             //['2']

set.remove(2);
console.log(set.values());           //[]

Tags:集合   
作者:网络 来源:qq_3553482