1. 手写集合
集合是一种保存不重复数据的数据结构,和ES6中的Set类类似。
- add(element) 添加元素
- delete(element) 删除元素
- has(element) 是否包含某元素
- clear() 删除所有元素
- size() 返回元素个数
- values() 返回由所有元素组成的数组
class SetCustom {
constructor() {
this.items = {};
}
add(element) {
if (this.has(element)) return false;
this.items[element] = element;
return true;
}
delete(element) {
if (this.has(element)) {
delete this.items[element];
return true;
}
return false;
}
has(element) {
return Object.prototype.hasOwnProperty.call(this.items, element);
}
size() {
return Object.keys(this.items).length;
}
clear() {
this.items = {};
}
values() {
return Object.values(this.items);
}
}
let set = new SetCustom();
set.add('Alice');
set.add('Bob');
set.add('Jack');
set.delete('Bob');
console.log('values', set.values());
console.log('size', set.size());
2. 集合的运用
- 并集:对于给定的两个集合,返回包含两个集合中所有元素的新集合。
- 交集:对于给定的两个集合,返回两个集合共有的元素的新集合。
- 差集:对于给定的两个集合,返回存在于第一个集合但是不存在于第二个集合的元素组成的新集合。
- 子集:验证一个集合是不是另一个元素的子集。
class Set extends SetCustom {
constructor() {
super();
}
// 并集
union(otherSet) {
let result = new Set();
let thisValue = this.values();
let otherValue = otherSet.values();
[...thisValue, ...otherValue].forEach(item => {
result.add(item);
});
return result;
}
// 交集
intersection(otherSet) {
let thisValue = this.values();
let result = new Set();
thisValue.forEach(item => {
if (otherSet.has(item)) {
result.add(item);
}
});
return result;
}
// 差集
difference(otherSet) {
let thisValue = this.values();
let result = new Set();
thisValue.forEach(item => {
if (!otherSet.has(item)) {
result.add(item);
}
});
return result;
}
// 判断是否是子集
isSubsetOf(otherSet) {
if (this.size() > otherSet.size()) return false;
let isSubset = true;
this.values().forEach(item => {
if (!otherSet.has(item)) {
isSubset = false;
}
});
return isSubset;
}
}
let setTest = new Set();
let otherTest = new Set();
setTest.add('Alice');
setTest.add('Bob');
setTest.add('Jack');
otherTest.add('Alice');
otherTest.add('Vivian');
console.log(setTest.union(otherTest).values());
console.log(setTest.intersection(otherTest).values());
console.log(setTest.difference(otherTest).values());
console.log('isSubsetOf:', otherTest.isSubsetOf(setTest));
3. 多重集
能够保存重复数据的集合就是多重集。
class Multiset {
constructor() {
this.items = {};
}
add(element) {
if (this.has(element)) {
this.items[element].count += 1;
}
else {
this.items[element] = {
value: element,
count: 1
};
}
}
delete(element) {
if (this.has(element)) {
const thisValue = this.items[element];
if (thisValue.count === 1) {
delete this.items[element]
}
else {
thisValue.count -= 1;
}
return true;
}
return false;
}
has(element) {
return Object.prototype.hasOwnProperty.call(this.items, element);
}
size() {
let count = 0;
Object.keys(this.items).forEach(key => {
let element = this.items[key];
count += element.count;
});
return count;
}
values() {
let result = [];
console.log(this.items)
Object.keys(this.items).forEach(key => {
let element = this.items[key];
for (let i = 0; i < element.count; i++) {
result.push(element.value);
}
});
return result;
}
clear() {
this.items = {};
}
}
let multiset = new Multiset();
multiset.add('Alice');
multiset.add('Bob');
multiset.add('Jack');
multiset.add('Bob');
console.log('values', multiset.values());
console.log('size', multiset.size());