Set集合
概念
集合:集合是由一组无序且唯一的项组成的。
空集:不包含任何元素的集合。(注意:空集并不是无,它只是里边没有放任何元素,相当于是一个空袋子)
创建一个集合类
class Set {
constructor () {
this.items = {}
}
}
这里有一个细节,使用对象表示集合而不是数组,JavaScript的对象不允许一个指针指向两个不同的属性,这可以保证集合里的元素都是唯一的。不过,也可以使用数组来实现。
集合的一些可用方法
- add(element):向集合中添加元素
- delete(element):删除集合中的元素
- has(element):判断集合中是否有要查找的元素
- clear():清空集合
- size():获取集合中的元素数量
- values():将集合中的元素以数组的形式返回
- union(otherSet):返回两个集合的并集
- intersection(otherSet):返回两个集合的交集
- subtraction(otherSet):返回两个集合的差集
- isSubSetOf(otherSet):判断当前集合是否是另一个集合的子集
话不多说,开干……
首先应该实现has
方法,在集合新增和删除时候都要先判断当前集合中是否存在该元素,需要使用到这个方法
has (element) {
return Object.prototype.hasOwnProperty.call(this.items, element)
}
在这里也可以使用 this.items.hasOwnProperty(element)
来实现,但是不太安全,因为hasOwnProperty
方法可能会被覆盖重写。
接下来是add
方法,毕竟所有的增删改查都是从新增开始的
add (element) {
if (this.has(element)) {
return false // 如果当前集合中已经存在了该元素,则新增失败
}
this.items[element] = element
return true
}
delete
方法
delete (element) {
if (!this.has(element)) {
return false // 集合中都没有该元素,那必然只能返回删除失败了
}
delete this.items[element] // 因为使用的对象表示的集合,所以可以直接使用delete关键字删除
return true
}
clear
方法
clear () {
this.items = {} // 这没啥说的,直接恢复出厂设置就行
return true
}
size
方法
size () {
return Object.keys(this.items).length
}
// Object.keys() 方法返回存有当前对象属性名的数组
values()
方法
values () {
return Object.values(this.items)
}
// Object.values() 方法返回存有当前对象属性值的数组
union(otherSet)
方法
// 撸码之前先了解一下并集的概念
// 并集:元素x存在于集合A中或者存在于集合B中,说人话就是将两个集合的元素合并去重组成一个新的集合,这个新的集合就是它们的并集
union (otherSet) {
const unionSet = new Set()
for (const element of this.values().concat(otherSet.values())) {
unionSet.add(element)
}
return unionSet
}
intersection(otherSet)
方法
// 交集:元素x既存在于集合A中也存在于集合B中,翻译过来就是两个集合相同的部分的元素组成的集合就是它们的交集
intersection (otherSet) {
const intersectionSet = new Set()
if (otherSet.size() === 0 || this.size() === 0) {
// 如果有一个集合是空集,那这两个集合的交集也必然是空集
return intersectionSet
}
for (const element of this.values()) {
if (otherSet.has(element)) {
// 如果集合A中有的元素集合B中也有,那就把它放在交集中
intersectionSet.add(element)
}
}
return intersectionSet
}
subtraction(otherSet)
方法
// 差集:元素x存在于集合A中而不存在与集合B中,也就是说,集合A中有的而集合B中没有的元素组成的集合就是它们的差集
subtraction (otherSet) {
const subtractionSet = new Set()
for (const element of this.values()) {
if (!otherSet.has(element)) {
// 将集合A中有的而集合B中没有的元素放入差集中
subtractionSet.add(element)
}
}
return subtractionSet
}
isSubSetOf(otherSet)
// 子集:集合A中的每一个元素在集合B中也都存在
isSubSetOf (otherSet) {
if (otherSet.size() === 0 && this.size() !== 0) {
// 如果集合B是一个空集而集合A非空,那集合A必然不是集合B的子集
return false
}
for (const element of this.values()) {
if (!otherSet.has(element)) {
// 集合A中有而集合B中没有
return false
}
}
return true
}
ES6中的Set
在ES6中也为我们提供了一个Set对象,它返回的是一个可迭代对象,它的entries方法会返回一个新的迭代器对象,里边包含了当前Set对象中按插入顺序排列的所有值的[value, value]数组,这里和我们的实现类似,对象的键和值相等。
ES6的Set对象并灭有给我们提供并交差集合的运算,如果有需要,我们也也可以模拟,这里就不展开写了