集合是由一组无序且唯一(即不能重复)的项组成的。
我们可以把集合想象成一个既没有重复元素,也没有顺序概念的数组。
在数学中,集合是一组不同的对象(的集)。比如说,一个由大于或等于0的正数组成的自然数集合,即N={0,1,2,3,4,5,…}。
集合中的对象列表用大括号({})包围。
一、集合的创建
function Set () {
//使用对象而不是数组来表示集合
//JavaScript的对象不允许一个键指向两个不同的属性,保证了集合里的元素都是唯一的
var items = {};
/*
has(value)
如果值在集合中,返回true,否则返回false
*/
this.has = function(value){
//return value in items;
//更好的实现方式
return items.hasOwnProperty(value);//hasOwnProperty()方法返回一个表明对象是否具有特定属性的布尔值
};
/*
add(value)
向集合添加一个新的项
*/
this.add = function(value){
if (!this.has(value)) {
items[value] = value;
return true;
}
return false;
};
/*
remove(value)
从集合移除一个值
*/
this.remove = function(value){
if (this.has(value)) {
delete items[value];
return true;
}
return false;
};
/*
clear()
移除集合中的所有项
*/
this.clear = function(){
items = {};
};
/*
size()
返回集合所包含元素的数量
*/
this.size = function(){
return Object.keys(items).length;
};
//以上代码只能在现代浏览器中运行,而下面的代码在任何浏览器中都能执行
this.sizeLegacy = function(){
var count = 0;
for (var prop in items) {
if (items.hasOwnProperty(prop)) {
++count;
}
return count;
}
};
/*
values()
返回一个包含集合中所有值的数组
*/
this.values = function(){
return Object.keys(items);
};
//以上代码只能在现代浏览器中运行,而下面的代码在任何浏览器中都能执行
this.valuesLegacy = function(){
var keys = [];
for (var key in items) {
keys.push(key);
}
return keys;
};
}
二、使用Set类
var set = new Set();
set.add(1);
console.log(set.values()); //输出["1"]
console.log(set.has()); //输出false
console.log(set.size()); //输出1
set.add(2);
console.log(set.values()); //输出["1", "2"]
console.log(set.has()); //输出false
console.log(set.size()); //输出2
set.remove(1);
console.log(set.values()); //输出["2"]
set.remove(2);
console.log(set.values()); //输出[]
在控制台的输出结果如下:
三、集合操作
1、并集union()
对于给定的两个集合,返回一个包含两个集合中所有集合的新集合。
并集的数学概念,集合A和B的并集,表示为A∪B,定义如下:A∪B={x|x∈A,或x∈B},意思是x(元素)存在于A中,或x存在于B中。
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;
};
测试一下:
var setA = new Set();
setA.add(1);
setA.add(2);
setA.add(3);
var setB = new Set();
setB.add(3);
setB.add(4);
setB.add(5);
setB.add(6);
var unionAB = setA.union(setB);
console.log(unionAB.values());
2、交集intersection()
对于给定的两个集合,返回一个包含两个集合中共有的新集合。
交集的数学概念,集合A和B的交集,表示为A∩B,定义如下:A∩B= {x|x∈A∧x∈B},意思是元素)存在于A中,且x存在于B中。
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])) {
intersectionSet.add(values[i]);
}
}
return intersectionSet;
};
测试一下:
var setA = new Set();
setA.add(1);
setA.add(2);
setA.add(3);
var setB = new Set();
setB.add(2);
setB.add(3);
setB.add(4);
var intersectionAB = setA.intersection(setB);
console.log(intersectionAB.values());
3、差集difference()
对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合。
差集的数学概念,集合A和B的差集,表示为A-B,定义如下:A-B={x∣x∈A,且x∉B},意思是x(元素)存在于A中,且x不存在于B中。
this.difference = function(otherSet){
var differenceSet = new Set();
var values = this.values();
for (var i = 0; i < values.length; i++) {
if (!otherSet.has(values[i])) {
differenceSet.add(values[i]);
}
}
return differenceSet;
};
测试一下:
var setA = new Set();
setA.add(1);
setA.add(2);
setA.add(3);
var setB = new Set();
setB.add(2);
setB.add(3);
setB.add(4);
var differenceAB = setA.difference(setB);
console.log(differenceAB.values());
4、子集subset()
验证一个给定集合是否是另一集合的子集。
子集的数学概念,集合A是B的子集(或集合B包含了A),表示为A⊆B,定义如下:∀x{x∈A→x∈B},意思是集合A中的每一个x(元素),也需要存在于B中。
this.subset = function(otherSet){
if (this.size() > otherSet.size()) {
return false;
}
else {
var values = this.values();
for (var i = 0; i < values.length; i++) {
if (!otherSet.has(values[i])) {
return false;
}
}
return true;
}
};
测试一下:
var setA = new Set();
setA.add(1);
setA.add(2);
var setB = new Set();
setB.add(1);
setB.add(2);
setB.add(3);
var setC = new Set();
setC.add(2);
setC.add(3);
setC.add(4);
console.log(setA.subset(setB));
console.log(setA.subset(setC));