从数学上我们已经了解到集合的基本概念,集合是由一组无序且唯一的元素组成。可以把集合想象成一个既没有重复元素,也没有顺序的数组。
一、创建一个集合
以下是集合(Set类)的骨架:
function Set(){
var items = {};
}
在集合中我们使用对象来表示集合,当然也可以使用数组来实现。JavaScript的对象不允许一个键指向两个不同的属性,也保证了集合里的元素都是唯一的。
接下来,按照惯例,需要声明一些集合的方法。
add(value):向集合中添加一个新的元素。
remove(value):从集合中移除一个元素。
has(value):如果集合存在这个元素,则返回true,否则返回false。
clear():移除集合中所有的元素。
size():返回集合中包含元素的个数。
values():返回包含集合中所有元素的数组。
1、has(value)方法
首先来实现一下has(value)方法,因为后面其它方法会调用这个方法。
this.has=function(value){
return items.hasOwnProperty(Value);
//也可以使用return value in items;
};
既然我们使用对象来存储集合的值,就可以用JavaScript的in操作符来验证给定的值是否是items对象的属性。同时所有的?JavaScript对象都有hasOwnProperty方法,这个方法返回一个表明对象是否具有特定属性的布尔值。
2、add(value)方法
接下来实现add方法:
this.add=function(value){
if(!this.has(value)){
items[value]=value;
return true;
}
return false;
};
对于给定的value值,需要先检查集合中是否存在于集合中,如果不存在就把value值添加到集合中,并且返回true,若集合中已经存在这个value值,就返回一个false,表示没有添加成功。
3、remove和clear方法
下面来实现一下remove方法:
this.remove=function(value){
if(this.has(value)){
delete items[value];
return true;
}
return false;
};
同样需要先验证元素知否存在于集合中。既然使用对象来存储集合的元素,就可以使用delete操作符从items对象中基础属性。
clear方法:
this.clear=function(){
items={};
};
赋一个空对象给items,就完成了移除全部集合元素的任务,是不是很简单呢?
4、size方法
在这里size方法有三种实现方式。
第一种方法,使用一个length变量,每当使用add或者remove的时候,动态的控制length的值。
第二种方法,使用JavaScript内建的Object类的一个内建函数:
this.size=function(){
return Object.keys(items).length;
};
JavaScript的Object类有一个keys方法,它返回一个包含给定对象所有属性的数组,在这种情况下可以使用数组的length属性来返回items对象的属性个数。但是这段代码只能在IE9以上版本、Firefox4以上版本、Chrome5以上版本…
第三种方法,手动提取items对象的每一个属性,记录属性的个数并返回这个数字,并且可以在任何浏览器运行。
this.sizeLegacy=function(){
var count=0;
for(var prop in items){
if(items.hasOwnProperty(prop))
++count;
}
return count;
};
5、values()方法
value方法同样提取items对象的所有属性,以数组的形式返回:
this.values=function(){
//必须在比较高级的浏览器中工作才能运行
return Object.keys(items);
};
//在所有的浏览器中都能运行
this.valuesLegacy=function(){
var keys=[];
for(var key in items){
keys.push(key);
}
return keys;
};
6、完整的Set类
function Set(){
var items={};//在这里使用对象来表示集合,当然数组也可以实现
this.has=function(value){
//javascript对象都有hasOwnProperty方法,这个方法返回一个表明对象是否具有特定属性的布尔值
return items.hasOwnProperty(Value);
//也可以使用return value in items;
};
this.add=function(value){
if(!this.has(value)){
items[value]=value;
return true;
}
return false;
};
this.remove=function(value){
if(this.has(value)){
delete items[value];
return true;
}
return false;
};
this.clear=function(){
items={};
};
this.size=function(){
//法一:
return Object.keys(items).length;
//法二:使用一个length变量,当使用add或者remove方法时动态控制它的值
//法三:
//this.sizeLegacy=function(){
//var count=0;
//for(var prop in items){
//if(items.hasOwnProperty(prop))
//++count;
//}
//return count;
//};
};
this.values=function(){
//必须在比较高级的浏览器中工作才能运行
return Object.keys(items);
//若想在任意浏览器中都能执行,用下面这段代码
//this.valuesLegacy=function(){
//var keys=[];
//for(var key in items){
//keys.push(key);
//}
//return keys;
//};
};
二、集合的操作
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++){
union.add(values[i]);
}
return unionSet;
};
2、交集
this.intersection = function(otherSet){
var intersectionSet = new Set();
var values = this.values();
for(var i=0;i<values.length;i++){
if(otherSet.has(values[i])){
interectionSet.add(values[i]);
}
}
return intersectionSet;
}
3、差集
this.difference = function(otherSet){
var differenceSet = new Set();
values = this.values;
for(var i=0;i<values.length;i++){
if(!otherSet.has(values[i])){
differenceSet.add(values[i]);
}
}
return differenceSet;
}
4、子集
this.subSet = function(otherSet){
if(this.size<otherSet.size){
return false;
}else{
values = this.values;
for(var i=0;i<values.length;i++){
if(!otherSet.has(values[i])){
return false;
}
}
return true;
}
};