對集合可以進行如下操作。
並集:對於給定的兩個集合,返回一個包含兩個集合中所有元素的新集合。
交集:對於給定的兩個集合,返回一個包含兩個集合中共有元素的新集合。
差集:對於給定的兩個集合,返回一個包含所有存在於第一個集合且不存在於第二個集合的元素的新集合。
子集:驗證一個給定集合是否是另一集合的子集。
6.3.1 並集
並集的數學概念是集合A和集合B的並集,表示為:
A∪B
該集合定義如下:
A∪B = { x | x ∈ Aˇx ∈ B }
意思是x(元素)存在於A中,或x存在於B中。下圖展示了並集操作:
現在來實現Set
類的union
方法:
this.union = function(otherSet){
let unionSet = new Set; //{1}
let values = this.values; //{2}
for (let i=0; i<values.length; i++){
unionSet.add(values[i]);
}
values = otherSet.values; //{3}
for (let i=0; i<values.length; i++){
unionSet.add(values[i]);
}
return unionSet;
};
首先需要創建一個新的集合,代表兩個集合的並集(行{1}
)。接下來,獲取第一個集合(當前的Set
類實例)所有的值(values
),遍歷並全部添加到代表並集的集合中(行{2}
)。然後對第二個集合做同樣的事(行{3}
)。最後返回結果。
測試一下上面的代碼:
let setA = new Set;
setA.add(1);
setA.add(2);
setA.add(3);
let setB = new Set;
setB.add(3);
setB.add(4);
setB.add(5);
setB.add(6);
let unionAB = setA.union(setB);
console.log(unionAB.values);
輸出為[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]
。注意元素3
同時存在於A和B中,它在結果的集合中只出現一次。
6.3.2 交集
交集的數學概念是集合A和集合B的交集,表示為:
A∩B
該集合定義如下:
A∩B = { x | x ∈ AΛx ∈ B }
意思是x(元素)存在於A中,且x 存在於B中。下圖展示了交集操作:
現在來實現Set
類的intersection
方法:
this.intersection = function(otherSet){
let intersectionSet = new Set; //{1}
let values = this.values;
for (let i=0; i<values.length; i++){ //{2}
if (otherSet.has(values[i])){ //{3}
intersectionSet.add(values[i]); //{4}
}
}
return intersectionSet;
}
intersection
方法需要找到當前Set
實例中,所有也存在於給定Set
實例中的元素。首先創建一個新的Set
實例,這樣就能用它返回共有的元素(行{1}
)。接下來,遍歷當前Set
實例所有的值(行{2}
),驗證它們是否也存在於otherSet
實例(行{3}
)之中。可以用這一章前面實現的has
方法來驗證元素是否存在於Set
實例中。然後,如果這個值也存在於另一個Set
實例中,就將其添加到創建的intersectionSet
變量中(行{4}
),最後返回它。
做些測試:
let setA = new Set;
setA.add(1);
setA.add(2);
setA.add(3);
let setB = new Set;
setB.add(2);
setB.add(3);
setB.add(4);
let intersectionAB = setA.intersection(setB);
console.log(intersectionAB.values);
輸出為[\"2\", \"3\"]
,因為2
和3
同時存在於兩個集合中。
6.3.3 差集
差集的數學概念是集合A和集合B的差集,表示為:A-B,定義如下:
A-B = { x | x ∈ A Λ x ∉ B }
意思是x(元素)存在於A中,且x不存在於B 中。下圖展示了集合A和B 的差集操作:
現在來實現Set
類的difference
方法:
this.difference = function(otherSet){
let differenceSet = new Set; //{1}
let values = this.values;
for (let i=0; i<values.length; i++){ //{2}
if (!otherSet.has(values[i])){ //{3}
differenceSet.add(values[i]); //{4}
}
}
return differenceSet;
};
intersection
方法會得到所有同時存在於兩個集合中的值。而difference
方法會得到所有存在於集合A但不存在於B的值。因此這兩個方法在實現上唯一的區別就是行{3}
。只獲取不存在於otherSet
實例中的值,而不是也存在於其中的值。行{1}
、{2}
和{4}
是完全相同的。
(用跟intersection
部分相同的集合)做些測試:
let setA = new Set;
setA.add(1);
setA.add(2);
setA.add(3);
let setB = new Set;
setB.add(2);
setB.add(3);
setB.add(4);
let differenceAB = setA.difference(setB);
console.log(differenceAB.values);
輸出為[\"1\"]
,因為1
是唯一一個僅存在於setA
的元素。
6.3.4 子集
我們要介紹的最後一個集合操作是子集。子集的數學概念是集合A是集合B的子集(或集合B包含了A),表示為:
A⊆B
該集合定義如下:
∀x { x ∈ A → x ∈ B }
意思是集合A中的每一個x(元素),也需要存在於B 中。下圖展示了集合A是集合B 的子集:
現在來實現Set
類的subset
方法:
this.subset = function(otherSet){
if (this.size > otherSet.size){ //{1}
return false;
} else {
let values = this.values;
for (let i=0; i<values.length; i++){ //{2}
if (!otherSet.has(values[i])){ //{3}
return false; //{4}
}
}
return true; //{5}
}
};
首先需要驗證的是當前Set
實例的大小。如果當前實例中的元素比otherSet
實例更多,它就不是一個子集(行{1}
)。子集的元素個數需要小於或等於要比較的集合。
接下來要遍歷集合中的所有元素(行{2}
),驗證這些元素也存在於otherSet
中(行{3}
)。如果有任何元素不存在於otherSet
中,就意味著它不是一個子集,返回false
(行{4}
)。如果所有元素都存在於otherSet
中,行{4}
就不會被執行,那麼就返回true
(行{5}
)。
檢驗一下上面的代碼效果如何:
let setA = new Set;
setA.add(1);
setA.add(2);
let setB = new Set;
setB.add(1);
setB.add(2);
setB.add(3);
let setC = new Set;
setC.add(2);
setC.add(3);
setC.add(4);
console.log(setA.subset(setB));
console.log(setA.subset(setC));
我們有三個集合:setA
是setB
的子集(因此輸出為true
),然而setA
不是setC
的子集(setC
只包含了setA
中的2
,而不包含1
),因此輸出為false
。