数学集合,它的意思是,一堆数据,在同一个范畴里,可以有重复的数据出现在一个集合中,这些数据没有顺序,互相之间没有关系,直接跟集合本身关联。
编程范畴中的集合,不允许重复的数据出现,同时也没有顺序。
跟数组比,就是无序的,无下标的属性。也就是读写它没数组方便了。

特征

  • 无序的数据堆,无下标
  • 不允许重复的数据出现

Set 类:ES6中的集合类

不允许重复!
用哈希表会更好!后面会学到。目前只能用Object对象来封装了。
截屏2020-03-31 下午4.05.25.png

用对象来封装

以前我突发奇想,用对象的赋值方法来去重数组,觉得自己相当聪明的。。。
现在感觉自己还是眼界太窄了,,,这都早就是套路了!
对象的赋值操作,确实可以去重!但是局限性太大了!

先看看封装:

  1. //集合
  2. class Set {
  3. constructor(items = {}) {
  4. this.items = items;
  5. }
  6. has(val) {
  7. //数字或者字符串强制转化为字符串了,,,
  8. return this.items.hasOwnProperty(val);
  9. }
  10. add(val) {
  11. return this.has(val) ? false : this.items[val] = val;
  12. }
  13. remove(val) {
  14. return this.has(val) ?
  15. delete this.items[val] : false;
  16. }
  17. size() {
  18. return Object.keys(this.items).length;
  19. }
  20. clear() {
  21. return this.items = {};
  22. }
  23. values() {
  24. return Object.keys(this.items).map(
  25. key => this.items[key]
  26. );
  27. }
  28. }
  29. const set = new Set({a: "a"});
  30. set.add(2);
  31. set.add("b");
  32. set.add("3");
  33. console.log(
  34. set, set.has('2'),
  35. set.remove(3),
  36. set.size(),
  37. set.values()
  38. );

缺点,

字符串与数字不可区分,强制转化为字符串,因为靠的是对象的键key做到了,不重复。
同理,只能接受字符串或者数字作为节点。也是限制!

操作

截屏2020-03-31 下午5.05.24.png

并集

截屏2020-03-31 下午5.09.45.png

  1. class Union extends Set {
  2. constructor(arr,initData) {
  3. super(initData);
  4. if (!Array.isArray(arr) || arr.find(
  5. item => !(item instanceof Set)
  6. )) {
  7. throw new Error("Union 必须要接收一个Set类组成的数组参数!");
  8. }
  9. this.init(arr);
  10. }
  11. init(arr) {
  12. arr.map(
  13. list => {
  14. if (list instanceof Set) {
  15. const isEmpty = this.size() === 0;
  16. list.values().map(
  17. val => isEmpty ? this.add(val) :
  18. !this.has(val) && this.add(val)
  19. );
  20. }
  21. }
  22. );
  23. }
  24. }
  25. const set1 = new Set({
  26. a:'a',b:'b',c:'c',4:4,6:'6'
  27. })
  28. const set2 = new Set({
  29. b:'b',c:'c',4:'4',7:'7',l:'l'
  30. })
  31. const union = new Union([set1,set2])
  32. console.log(union);

交集

截屏2020-03-31 下午5.58.59.png

  1. // 交集
  2. class Intersection extends Set{
  3. constructor(set1,set2) {
  4. super();
  5. this.init(set1,set2)
  6. }
  7. init(set1,set2){
  8. set1.values().map(
  9. val=>set2.has(val) && this.add(val)
  10. )//所有的判断的has方法,都是判断的字符串形式的key,
  11. //这里其实是很强制性的吧数字也给转化为字符串了
  12. }
  13. }
  14. const intersection = new Intersection(set1,set2)
  15. console.log(intersection);

差集

截屏2020-03-31 下午6.10.27.png

  1. class Set {
  2. ******
  3. ****
  4. ***
  5. //差集:因为这是一个实例的操作,所以放Set里了,其实上面的并集也是差不多的,
  6. //不改了,面向对象的想法可松可紧
  7. deference(set) {
  8. if (!set instanceof Set){
  9. throw new Error('参数必须是Set类的实例')
  10. }
  11. const res = new Set();
  12. this.values().map(
  13. val => !set.has(val) && res.add(val)
  14. );
  15. return res;
  16. }
  17. }

子集

截屏2020-03-31 下午6.27.38.png

也是一个实例的方法,,,就不新增类了。

  1. class Set {
  2. ****
  3. *****
  4. ****
  5. subSet(set) {
  6. if (!set instanceof Set) {
  7. throw new Error("参数必须是Set类的实例");
  8. }
  9. return this.values().find( //find方法的普及率不高,,,我也很奇怪,,,返回的undefined会过滤掉0,‘0’。
  10. val => !set.has(val)
  11. ) === undefined ? true :false
  12. );
  13. }
  14. }

字典

  • 完全符合JS对象:键值对,映射关系!跟集合的区别就是键值对
  • 无序,不可重复键。很像数据库里的表啊。

截屏2020-03-31 下午7.06.55.png

截屏2020-03-31 下午7.07.33.png