ES6的JavaScript数据结构实现之集合
目的:ES6标准下的JS数据结构的一些实现代码。(作为记录和启发)
内容:集合。(未完成,待继续)
所有源码在我的Github上(如果觉得不错记得给星鼓励我哦):ES6的JavaScript数据结构实现之集合
注:Set类在ES6中已经提供了原生的Set结构。
一、基础数据结构
1、集合(非ES6自带的原生Set)
1 class Set { 2 constructor() { 3 this.items = {}; 4 } 5 has(element) { 6 return Object.prototype.hasOwnProperty.call(this.items, element); 7 } 8 add(element) { 9 if (!this.has(element)) { 10 this.items[element] = element; 11 return true; 12 } 13 return false; 14 } 15 delete(element) { 16 if(this.has(element)) { 17 delete this.items[element]; 18 return true; 19 } 20 return false; 21 } 22 clear() { 23 this.items = {}; 24 } 25 size() { 26 return Object.keys(this.items).length; 27 } 28 values() { 29 return Object.values(this.items); 30 } 31 union(otherSet) { 32 const unionSet = new Set(); 33 this.values().forEach(value => unionSet.add(value)); 34 otherSet.values().forEach(value => unionSet.add(value)); 35 return unionSet; 36 } 37 intersection(otherSet) { 38 const intersectionSet = new Set(); 39 const values = this.values(); 40 const otherValues = otherSet.values(); 41 let biggerSet = values; 42 let smallerSet = otherValues; 43 if (otherValues.length - values.length > 0) { 44 biggerSet = otherValues; 45 smallerSet = values; 46 } 47 smallerSet.forEach(value => { 48 if (biggerSet.includes(value)) { 49 intersectionSet.add(value); 50 } 51 }); 52 return intersectionSet; 53 } 54 difference(otherSet) { 55 const differenceSet = new Set(); 56 this.values().forEach(value => { 57 if (!otherSet.has(value)) { 58 differenceSet.add(value); 59 } 60 }); 61 return differenceSet; 62 } 63 isSubsetOf(otherSet) { 64 if (this.size() > otherSet.size()) { 65 return false; 66 } 67 let isSubset = true; 68 this.values().every(values => { 69 if(!otherSet.has(values)) { 70 isSubset = false; 71 return false; 72 } 73 return true; 74 }); 75 return isSubset; 76 } 77 78 isEmpty() { 79 return this.size() === 0; 80 } 81 toString() { 82 if (this.isEmpty()) { 83 return ''; 84 } 85 const values = this.values(); 86 let objString = `${values[0]}`; 87 for (let i = 1; i < values.length; i++) { 88 objString = `${objString},${values[i].toString()}`; 89 } 90 return objString; 91 } 92 93 94 } 95 96 const set = new Set(); 97 set.add(1); 98 set.add(2); 99 set.add(3); 100 console.log(set); 101 set.delete(1); 102 console.log(set); 103 console.log(set.size()); 104 console.log(set.values()); 105 const setB = new Set(); 106 setB.add(3); 107 setB.add(5); 108 setB.add(6); 109 console.log(setB); 110 console.log(set.union(setB)); 111 console.log(set.intersection(setB)); 112 console.log(set.difference(setB)); 113 console.log(setB.difference(set)); 114 console.log(set.isSubsetOf(setB)); 115 const setC = new Set(); 116 setC.add(5); 117 setC.add(6); 118 console.log(setC.isSubsetOf(setB));
2、ES6原生的Set类。(ES6中的原生的Set没有交、并、差运算,需要我们自己写。同时,我们可以结合使用扩展运算符,把集合转为为数组,再对数组进行运算,再转回集合。)
1 const set = new Set(); 2 3 set.add(1); 4 console.log(set.values()); // outputs @Iterator 5 console.log(set.has(1)); // outputs true 6 console.log(set.size); // outputs 1 7 8 set.add(2); 9 console.log(set.values()); // outputs [1, 2] 10 console.log(set.has(2)); // true 11 console.log(set.size); // 2 12 13 set.delete(1); 14 console.log(set.values()); // outputs [2] 15 16 set.delete(2); 17 console.log(set.values()); // outputs [] 18 19 const setA = new Set(); 20 setA.add(1); 21 setA.add(2); 22 setA.add(3); 23 24 const setB = new Set(); 25 setB.add(2); 26 setB.add(3); 27 setB.add(4); 28 29 // --------- Union ---------- 30 const union = (set1, set2) => { 31 const unionAb = new Set(); 32 set1.forEach(value => unionAb.add(value)); 33 set2.forEach(value => unionAb.add(value)); 34 return unionAb; 35 }; 36 console.log(union(setA, setB)); 37 38 console.log(new Set([...setA, ...setB])); 39 40 // --------- Intersection ---------- 41 const intersection = (set1, set2) => { 42 const intersectionSet = new Set(); 43 set1.forEach(value => { 44 if (set2.has(value)) { 45 intersectionSet.add(value); 46 } 47 }); 48 return intersectionSet; 49 }; 50 console.log(intersection(setA, setB)); 51 52 console.log(new Set([...setA].filter(x => setB.has(x)))); 53 54 // alternative - works on FF only 55 // console.log(new Set([x for (x of setA) if (setB.has(x))])); 56 57 // --------- Difference ---------- 58 const difference = (set1, set2) => { 59 const differenceSet = new Set(); 60 set1.forEach(value => { 61 if (!set2.has(value)) { 62 differenceSet.add(value); 63 } 64 }); 65 return differenceSet; 66 }; 67 console.log(difference(setA, setB)); 68 69 console.log(new Set([...setA].filter(x => !setB.has(x)))); 70 71 // alternative - works on FF only 72 // console.log(new Set([x for (x of setA) if (!setB.has(x))]));
Talk is cheap, code the code.