数学集合,它的意思是,一堆数据,在同一个范畴里,可以有重复的数据出现在一个集合中,这些数据没有顺序,互相之间没有关系,直接跟集合本身关联。
编程范畴中的集合,不允许重复的数据出现,同时也没有顺序。
跟数组比,就是无序的,无下标的属性。也就是读写它没数组方便了。
特征
- 无序的数据堆,无下标
- 不允许重复的数据出现
Set 类:ES6中的集合类
不允许重复!
用哈希表会更好!后面会学到。目前只能用Object对象来封装了。
用对象来封装
以前我突发奇想,用对象的赋值方法来去重数组,觉得自己相当聪明的。。。
现在感觉自己还是眼界太窄了,,,这都早就是套路了!
对象的赋值操作,确实可以去重!但是局限性太大了!
先看看封装:
//集合
class Set {
constructor(items = {}) {
this.items = items;
}
has(val) {
//数字或者字符串强制转化为字符串了,,,
return this.items.hasOwnProperty(val);
}
add(val) {
return this.has(val) ? false : this.items[val] = val;
}
remove(val) {
return this.has(val) ?
delete this.items[val] : false;
}
size() {
return Object.keys(this.items).length;
}
clear() {
return this.items = {};
}
values() {
return Object.keys(this.items).map(
key => this.items[key]
);
}
}
const set = new Set({a: "a"});
set.add(2);
set.add("b");
set.add("3");
console.log(
set, set.has('2'),
set.remove(3),
set.size(),
set.values()
);
缺点,
字符串与数字不可区分,强制转化为字符串,因为靠的是对象的键key做到了,不重复。
同理,只能接受字符串或者数字作为节点。也是限制!
操作
并集
class Union extends Set {
constructor(arr,initData) {
super(initData);
if (!Array.isArray(arr) || arr.find(
item => !(item instanceof Set)
)) {
throw new Error("Union 必须要接收一个Set类组成的数组参数!");
}
this.init(arr);
}
init(arr) {
arr.map(
list => {
if (list instanceof Set) {
const isEmpty = this.size() === 0;
list.values().map(
val => isEmpty ? this.add(val) :
!this.has(val) && this.add(val)
);
}
}
);
}
}
const set1 = new Set({
a:'a',b:'b',c:'c',4:4,6:'6'
})
const set2 = new Set({
b:'b',c:'c',4:'4',7:'7',l:'l'
})
const union = new Union([set1,set2])
console.log(union);
交集
// 交集
class Intersection extends Set{
constructor(set1,set2) {
super();
this.init(set1,set2)
}
init(set1,set2){
set1.values().map(
val=>set2.has(val) && this.add(val)
)//所有的判断的has方法,都是判断的字符串形式的key,
//这里其实是很强制性的吧数字也给转化为字符串了
}
}
const intersection = new Intersection(set1,set2)
console.log(intersection);
差集
class Set {
******
****
***
//差集:因为这是一个实例的操作,所以放Set里了,其实上面的并集也是差不多的,
//不改了,面向对象的想法可松可紧
deference(set) {
if (!set instanceof Set){
throw new Error('参数必须是Set类的实例')
}
const res = new Set();
this.values().map(
val => !set.has(val) && res.add(val)
);
return res;
}
}
子集
也是一个实例的方法,,,就不新增类了。
class Set {
****
*****
****
subSet(set) {
if (!set instanceof Set) {
throw new Error("参数必须是Set类的实例");
}
return this.values().find( //find方法的普及率不高,,,我也很奇怪,,,返回的undefined会过滤掉0,‘0’。
val => !set.has(val)
) === undefined ? true :false
);
}
}
字典
- 完全符合JS对象:键值对,映射关系!跟集合的区别就是键值对!
- 无序,不可重复键。很像数据库里的表啊。