数学中的集合
定义
所谓的一个集合,就是将数个对象归类而分成为一个或数个形态各异的大小整体。 一般来讲,集合是具有某种特性的事物的整体,或是一些确认对象的汇集。构成集合的事物或对象称作**[元素]** 或是 成员。集合的元素可以是任何事物,可以是人,可以是物,也可以是字母或数字等
符号
元素通常都是小写, 比如 ; 集合通常都是大写, 比如:
- 空集: , 空集是任何集合的子集
- 属于与不属于(元素和集合之间): ; 元素属于集合,则 表示 ; 元素不属于集合,则 表示
- 包含与被包含(集合之间):
- 交集:
- 并集:
- 真子集: 则 A 是 B的真子集
集合的特性
1. 无序性
一个集合中,每个元素的地位都是相同的,元素之间是无序的。
2. 互异性
一个集合中,任何两个元素都认为是不相同的,即每个元素只能出现一次。
3. 确定性
给定一个集合,任给一个元素,该元素或者属于或者不属于该集合,二者必居其一,不允许有模棱两可的情况出现。
集合运算
1. 并集
两个集合可以相"加", A 和 B的并集,就是将A 和 B的元素放在一起构成一个新的集合;
即
示例:
2. 交集
一个新的集合也可以通过两个集合均有的元素来构造;即
示例:
3.差集
两个集合也可以相"减", A - B, 则 构成的集合 属于A 但是 不属于B;
示例:
4.对称差
两个集合的对称差是只属于其中一个集合,而不属于另一个集合的元素组成的集合
示例:
Set 对象
Set对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。
实例方法
const set: Set<any> = new Set([1, 2, 3, 4]);
1. Set.prototype.add(value)
在Set对象尾部添加一个元素 , 如果Set对象中包含了 该元素, 则不会添加;
const set: Set<any> = new Set([1, 2, 3, 4]);
set.add(5)
console.log(set) // Set(5) { 1, 2, 3, 4, 5 }
set.add(1) // 因为 set里已经有1 这个元素了, 则不会添加
console.log(set) // Set(5) { 1, 2, 3, 4, 5 }
2. Set.prototype.clear()
移除Set对象内的所有元素。
const set: Set<any> = new Set([1, 2, 3, 4]);
set.clear()
console.log(set) // Set(0) {}
3. Set.prototype.delete(value)
移除Set中与这个值相等的元素,返回Set.prototype.has(value)在这个操作前会返回的值(即如果该元素存在,返回true,否则返回false)。Set.prototype.has(value)在此后会返回false; 可以理解成,是否删除成功
const set: Set<any> = new Set([1, 2, 3, 4]);
console.log(set.delete(1)) // true
console.log(set.delete(10)) // false
4. Set.prototype.entries()
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值的[value, value]数组
const set: Set<any> = new Set([1, 2, 3, 4]);
console.log(set.entries()) // [Set Entries] { [ 1, 1 ], [ 2, 2 ], [ 3, 3 ], [ 4, 4 ] }
5. Set.prototype.forEach(callback, context)
按照插入顺序,为Set对象中的每一个值调用一次callBackFn。如果提供了context参数,回调中的this会是这个参数。
const set: Set<any> = new Set([1, 2, 3, 4]);
set.forEach(function(key: any, value: any, set:Set<any> ){
console.log(value0, value1, set)
})
/***
1 1 Set(4) { 1, 2, 3, 4 }
2 2 Set(4) { 1, 2, 3, 4 }
3 3 Set(4) { 1, 2, 3, 4 }
4 4 Set(4) { 1, 2, 3, 4 }
***/
如果context传入值, 则 this指向该参数; 否则 默认的this 在 node环境: undefined 浏览器环境: window
const set: Set<any> = new Set([1, 2, 3, 4]);
set.forEach(function(this: any, key: any, value: any, set: Set<any>){
console.log(key, value, set, this)
}, {
author: '请叫我张先森'
})
/***
1 1 Set(4) { 1, 2, 3, 4 } { author: '请叫我张先森' }
2 2 Set(4) { 1, 2, 3, 4 } { author: '请叫我张先森' }
3 3 Set(4) { 1, 2, 3, 4 } { author: '请叫我张先森' }
4 4 Set(4) { 1, 2, 3, 4 } { author: '请叫我张先森' }
***/
6. Set.prototype.has(value)
返回一个布尔值,表示该值在Set中存在与否。
const set: Set<any> = new Set([1, 2, 3, 4]);
console.log(set.has(1)) // true
console.log(set.has(10)) // false
7. Set.prototype.keys()
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。
const set: Set<any> = new Set([1, 2, 3, 4]);
console.log(set.keys()) // [Set Iterator] { 1, 2, 3, 4 }
8. Set.prototype.values()
与 Set.prototype.keys()一样, 返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。
const set: Set<any> = new Set([1, 2, 3, 4]);
console.log(set.keys()) // [Set Iterator] { 1, 2, 3, 4 }
实现简易的数学集合操作
class CustomSet<T> {
private set: Set<T> ;
constructor (set?: Iterable<T> | null | undefined) {
this.set = new Set(set)
}
// 添加值
add (value: T) {
this.set.add(value)
}
// 判断值是否在
has(value: T):boolean {
return this.set.has(value)
}
// 删除值
delete (value: T): boolean {
return this.set.delete(value)
}
// 清除所有值
clear () {
this.set.clear()
}
// 返回[value, value]迭代器对象
entries(): IterableIterator<[T, T]> {
return this.set.entries()
}
// forEach方法
forEach(callback: (value: T, value2: T, set: Set<T>) => any, context: any = this) {
this.set.forEach(callback, context)
}
// 获取 所有元素值
keys ():IterableIterator<T>{
return this.set.keys()
}
// 获取 所有元素值
values ():IterableIterator<T>{
return this.set.keys()
}
// 差集
diff (set: CustomSet<any>): CustomSet<any> {
const _set: CustomSet<any> = new CustomSet<any>(this.set)
set.forEach(function(value: any) {
if (_set.has(value)) {
_set.delete(value)
}
})
return _set
}
// 并集
union (set: CustomSet<any>): CustomSet<any> {
const _set: CustomSet<any> = new CustomSet<any>(
[...this.values(), ...set.values()]
)
return _set
}
// 交集
intersection (set: CustomSet<any>): CustomSet<any> {
const _set: CustomSet<any> = new CustomSet<any>()
set.forEach((value: any) => {
if (this.has(value)) {
_set.add(value)
}
})
return _set
}
// 对称差
symmetricDiff (set: CustomSet<any>): CustomSet<any> {
const unions = this.union(set)
const diff = this.intersection(set)
const _set = unions.diff(diff)
return _set
}
}
测试:
const a = new CustomSet([1, 2, 3, 4 ,5])
const b = new CustomSet([2, 3, 4, 5, 6])
console.log(a.diff(b)) // CustomSet { set: Set(1) { 1 } }
console.log(a.union(b)) // CustomSet { set: Set(6) { 1, 2, 3, 4, 5, 6 } }
console.log(a.intersection(b)) // CustomSet { set: Set(4) { 2, 3, 4, 5 } }
console.log(a.symmetricDiff(b)) // CustomSet { set: Set(2) { 1, 6 } }