定义
Set
对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用,是一种新集合类型。
基本API
- 可以使用
new
关键字和Set
构造函数创建一个空集合:
const set = new Set();
- 想要创建一个空集合同时初始化实例,可以传入一个可迭代对象
const set = new Set([1, 2, 3]);
返回 Set 中值得个数。
const set = new Set([2, 3, 6]);
console.log(set.size); // 3
在Set
对象尾部添加一个元素。返回该 Set
对象。
set.add(12); // 2, 3, 6, 12
移除值为 value
的元素,并返回一个布尔值来表示是否移除成功。
set.delete(3); // 2, 6, 12
返回一个布尔值,表示该值在 Set
中存在与否。
set.has(3); // false
set.has(12); // true
移除Set
对象内的所有元素。
set.clear();
set.size; // 0
迭代方法
Set
会维护值插入时的顺序,故会按照顺序迭代。集合实例可以提供一个迭代器,能以插入顺序生成集合内容。
通过上两种方法可以拿到这个迭代器。
const set = new Set(['one', 'two', 'three']);
for(const value of set.values()) {
console.log(value);
}
// 等价于
for(const value of set.keys()) {
console.log(value);
}
// one, two, three
返回一个新的迭代器对象,该对象包含 Set
对象中的按插入顺序排列的所有元素的值的 [value, value]
数组。
const set = new Set(['one', 'two', 'three']);
for(const value of set.entries()) {
console.log(value);
}
// [['one', 'one'], ['two', 'two'], ['three', 'three']]
不使用迭代器,使用回调的方式迭代每一个值。传入的回调接收的第二个参数,这个参数用于重写回调内部的this的值。
const set = new Set(['one', 'two', 'three']);
set.forEach((value, dupValue) => {
console.log(`${value}->${dupValue}`);
});
// one->one, two->two, three->three
转换为数组
const set = new Set([2, 3, 6]);
console.log([...set]); // [2, 3, 6]
const set = new Set([2, 3, 6]);
console.log(Array.from(set)); // [2, 3, 6]
集合操作
/**
* 基于Set的集合操作
* @function union 并集
* @function intersection 交集
* @function difference 差集
* @function symmetricDifference 对称差集
* @function cartesianProduct 笛卡尔积
* @function powerSet 幂集
*/
class XSet extends Set {
// 并集
union(...sets) {
return XSet.union(this, ...sets);
}
// 交集
intersection(...sets) {
return XSet.intersection(this, ...sets);
}
// 差集
difference(set) {
return XSet.difference(this, set);
}
// 对称差集
symmetricDifference(set) {
return XSet.symmetricDifference(this, set);
}
// 笛卡尔积
cartesianProduct(set) {
return XSet.cartesianProduct(this, set);
}
// 幂集
powerSet() {
return XSet.powerSet(this);
}
// 返回多个集合的并集
static union(thisSet, ...otherSets) {
const unionSet = new XSet(thisSet);
for (const setOrder of otherSets) {
for (const oValue of setOrder) {
unionSet.add(oValue);
}
}
return unionSet;
}
// 返回多个集合的交集
static intersection(thisSet, ...otherSets) {
const intersectionSet = new XSet(thisSet);
for (const order of intersectionSet) {
for (const setOrder of otherSets) {
if (!setOrder.has(order)) {
intersectionSet.delete(order);
}
}
}
return intersectionSet;
}
// 返回两个集合的差集
static difference(thisSet, otherSet) {
const differenceSet = new XSet(thisSet);
for (const oValue of otherSet) {
if (thisSet.has(oValue)) {
differenceSet.delete(oValue);
}
}
return differenceSet;
}
// 返回两个集合的对称差集
static symmetricDifference(thisSet, otherSet) {
return thisSet.union(otherSet).difference(thisSet.intersection(otherSet));
}
// 返回两个集合笛卡尔积
static cartesianProduct(thisSet, otherSet) {
const cartesianProductSet = new XSet();
for (const thisValue of thisSet) {
for (const oValue of otherSet) {
cartesianProductSet.add([thisValue, oValue]);
}
}
return cartesianProductSet;
}
// 返回一个集合的幂集
static powerSet(thisSet) {
const powerSet = new XSet().add(new XSet());
for (const thisValue of thisSet) {
for (const set of new XSet(powerSet)) {
powerSet.add(new XSet(set).add(thisValue));
}
}
return powerSet;
}
}
集合操作检验
let xSet = new XSet([1, 2, 3, 11]);
// 并集检验
console.log('并集:', xSet.union(new Set([1, 2, 6]), new Set([2, 10, 11]))); // 1, 2, 3, 6, 10, 11
// 交集检验
console.log('交集:', xSet.intersection(new Set([1, 2, 6, 11]), new Set([2, 3, 10, 11]))); // 2, 11
// 差集检验
console.log('差集:', xSet.difference(new Set([2, 6, 11, 20]))); // 1, 3, 6, 20
// 对称差集检验
console.log('对称差集:', xSet.symmetricDifference(new Set([2, 6, 11, 20]))); // 1, 3, 6, 20
// 笛卡尔积检验
console.log('笛卡尔积:', xSet.cartesianProduct(new Set([2, 6]))); // [1, 2], [1, 6], [2, 2], [2, 6], [3, 2], [3, 6], [11, 2], [11, 6]
// 幂集检验
console.log('幂集:', xSet.powerSet()); // 所有子集