Skip to content

Commit 5961185

Browse files
committedOct 22, 2017
chapter 06: [Sets]
1 parent 4ee46b1 commit 5961185

File tree

15 files changed

+1111
-2
lines changed

15 files changed

+1111
-2
lines changed
 

‎README.md

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Work in Progress.
1515
* 03: [Stacks](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter03)
1616
* 04: [Queues and Deques](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter04)
1717
* 05: [LinkedLists](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter05)
18+
* 06: [Sets](https://github.com/loiane/javascript-datastructures-algorithms/tree/third-edition/examples/chapter06)
1819

1920
### Third Edition Updates
2021

@@ -40,6 +41,8 @@ Work in Progress.
4041

4142
* Or open the `examples/index.html` file to easily nagivate through all examples:
4243

44+
* Demo: [https://javascript-ds-algorithms-book.firebaseapp.com](https://javascript-ds-algorithms-book.firebaseapp.com)
45+
4346
<img src="examples/examples-screenshot.png">
4447

4548
Happy Coding!

‎examples/PacktDataStructuresAlgorithms.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples/chapter06/01-Set.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="./../PacktDataStructuresAlgorithms.min.js"></script>
9+
<script src="01-Set.js"></script>
10+
</body>
11+
</html>

‎examples/chapter06/01-Set.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const { Set } = PacktDataStructuresAlgorithms;
2+
3+
const set = new Set();
4+
5+
set.add(1);
6+
console.log(set.values()); // outputs [1]
7+
console.log(set.has(1)); // outputs true
8+
console.log(set.size()); // outputs 1
9+
10+
set.add(2);
11+
console.log(set.values()); // outputs [1, 2]
12+
console.log(set.has(2)); // true
13+
console.log(set.size()); // 2
14+
15+
set.delete(1);
16+
console.log(set.values()); // outputs [2]
17+
18+
set.delete(2);
19+
console.log(set.values()); // outputs []
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="./../PacktDataStructuresAlgorithms.min.js"></script>
9+
<script src="02-SetOperations.js"></script>
10+
</body>
11+
</html>
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const { Set } = PacktDataStructuresAlgorithms;
2+
3+
// --------- Union ----------
4+
5+
let setA = new Set();
6+
setA.add(1);
7+
setA.add(2);
8+
setA.add(3);
9+
10+
let setB = new Set();
11+
setB.add(3);
12+
setB.add(4);
13+
setB.add(5);
14+
setB.add(6);
15+
16+
const unionAB = setA.union(setB);
17+
console.log(unionAB.values()); // [1, 2, 3, 4, 5, 6]
18+
19+
// --------- Intersection ----------
20+
21+
setA = new Set();
22+
setA.add(1);
23+
setA.add(2);
24+
setA.add(3);
25+
26+
setB = new Set();
27+
setB.add(2);
28+
setB.add(3);
29+
setB.add(4);
30+
31+
const intersectionAB = setA.intersection(setB);
32+
console.log(intersectionAB.values()); // [2, 3]
33+
34+
// --------- Difference ----------
35+
36+
setA = new Set();
37+
setA.add(1);
38+
setA.add(2);
39+
setA.add(3);
40+
41+
setB = new Set();
42+
setB.add(2);
43+
setB.add(3);
44+
setB.add(4);
45+
46+
const differenceAB = setA.difference(setB);
47+
console.log(differenceAB.values()); // [1]
48+
49+
// --------- Subset ----------
50+
51+
setA = new Set();
52+
setA.add(1);
53+
setA.add(2);
54+
55+
setB = new Set();
56+
setB.add(1);
57+
setB.add(2);
58+
setB.add(3);
59+
60+
const setC = new Set();
61+
setC.add(2);
62+
setC.add(3);
63+
setC.add(4);
64+
65+
console.log(setA.isSubsetOf(setB)); // true
66+
console.log(setA.isSubsetOf(setC)); // false

‎examples/chapter06/03-ES2015Set.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<script src="./../PacktDataStructuresAlgorithms.min.js"></script>
9+
<script src="03-ES2015Set.js"></script>
10+
</body>
11+
</html>

‎examples/chapter06/03-ES2015Set.js

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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+
// --------- Intersection ----------
39+
const intersection = (set1, set2) => {
40+
const intersectionSet = new Set();
41+
set1.forEach(value => {
42+
if (set2.has(value)) {
43+
intersectionSet.add(value);
44+
}
45+
});
46+
return intersectionSet;
47+
};
48+
console.log(intersection(setA, setB));
49+
50+
// alternative - works on FF only
51+
// console.log(new Set([x for (x of setA) if (setB.has(x))]));
52+
53+
// --------- Difference ----------
54+
const difference = (set1, set2) => {
55+
const differenceSet = new Set();
56+
set1.forEach(value => {
57+
if (!set2.has(value)) {
58+
differenceSet.add(value);
59+
}
60+
});
61+
return differenceSet;
62+
};
63+
console.log(difference(setA, setB));
64+
65+
// alternative - works on FF only
66+
// console.log(new Set([x for (x of setA) if (!setB.has(x))]));

‎examples/index.html

+9-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,15 @@
143143
</section>
144144
<section class="mdl-layout__tab-panel" id="scroll-tab-6">
145145
<div class="page-content">
146-
Soon.
146+
<div class="page-content mdl-layout--fixed-drawer">
147+
<div class="mdl-layout__drawer is-visible">
148+
<nav class="mdl-navigation">
149+
<a class="mdl-navigation__link" href="chapter06/01-Set.html">01-Set</a>
150+
<a class="mdl-navigation__link" href="chapter06/02-SetOperations.html">02-SetOperations</a>
151+
<a class="mdl-navigation__link" href="chapter06/03-ES2015Set.html">03-ES2015Set</a>
152+
</nav>
153+
</div>
154+
</div>
147155
</div>
148156
</section>
149157
<section class="mdl-layout__tab-panel" id="scroll-tab-7">

‎src/js/data-structures/set.js

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
export default class Set {
2+
constructor() {
3+
this.items = {};
4+
}
5+
add(value) {
6+
if (!this.has(value)) {
7+
this.items[value] = value;
8+
return true;
9+
}
10+
return false;
11+
}
12+
delete(value) {
13+
if (this.has(value)) {
14+
delete this.items[value];
15+
return true;
16+
}
17+
return false;
18+
}
19+
has(value) {
20+
return Object.prototype.hasOwnProperty.call(this.items, value);
21+
}
22+
values() {
23+
return Object.values(this.items);
24+
}
25+
union(otherSet) {
26+
const unionSet = new Set();
27+
this.values().forEach(value => unionSet.add(value));
28+
otherSet.values().forEach(value => unionSet.add(value));
29+
return unionSet;
30+
}
31+
intersection(otherSet) {
32+
const intersectionSet = new Set();
33+
const values = this.values();
34+
const otherValues = otherSet.values();
35+
let biggerSet = values;
36+
let smallerSet = otherValues;
37+
if (otherValues.length - values.length > 0) {
38+
biggerSet = otherValues;
39+
smallerSet = values;
40+
}
41+
smallerSet.forEach(value => {
42+
if (biggerSet.includes(value)) {
43+
intersectionSet.add(value);
44+
}
45+
});
46+
return intersectionSet;
47+
}
48+
difference(otherSet) {
49+
const differenceSet = new Set();
50+
this.values().forEach(value => {
51+
if (!otherSet.has(value)) {
52+
differenceSet.add(value);
53+
}
54+
});
55+
return differenceSet;
56+
}
57+
isSubsetOf(otherSet) {
58+
if (this.size() > otherSet.size()) {
59+
return false;
60+
}
61+
let isSubset = true;
62+
this.values().every(value => {
63+
if (!otherSet.has(value)) {
64+
isSubset = false;
65+
return false;
66+
}
67+
return true;
68+
});
69+
return isSubset;
70+
}
71+
isEmpty() {
72+
return this.size() === 0;
73+
}
74+
size() {
75+
return Object.keys(this.items).length;
76+
}
77+
clear() {
78+
this.items = {};
79+
}
80+
toString() {
81+
if (this.isEmpty()) {
82+
return '';
83+
}
84+
const values = this.values();
85+
let objString = `${values[0]}`;
86+
for (let i = 1; i < values.length; i++) {
87+
objString = `${objString},${values[i].toString()}`;
88+
}
89+
return objString;
90+
}
91+
}

‎src/js/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export { default as DoublyLinkedList } from './data-structures/doubly-linked-lis
1515
export { default as CircularLinkedList } from './data-structures/circular-linked-list';
1616
export { default as SortedLinkedList } from './data-structures/sorted-linked-list';
1717
export { default as StackLinkedList } from './data-structures/stack-linked-list';
18+
export { default as Set } from './data-structures/set';
1819

1920
export const util = _util;
2021

‎src/ts/data-structures/set.ts

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
export default class Set<T> {
2+
private items: any;
3+
4+
constructor() {
5+
this.items = {};
6+
}
7+
8+
add(value: T) {
9+
if (!this.has(value)) {
10+
this.items[value] = value;
11+
return true;
12+
}
13+
return false;
14+
}
15+
16+
delete(value: T) {
17+
if (this.has(value)) {
18+
delete this.items[value];
19+
return true;
20+
}
21+
return false;
22+
}
23+
24+
has(value: T) {
25+
// return this.items.hasOwnProperty(value);
26+
return Object.prototype.hasOwnProperty.call(this.items, value);
27+
}
28+
29+
values(): T[] {
30+
return Object.values(this.items);
31+
}
32+
33+
union(otherSet: Set<T>) {
34+
const unionSet = new Set<T>();
35+
36+
this.values().forEach(value => unionSet.add(value));
37+
otherSet.values().forEach(value => unionSet.add(value));
38+
39+
return unionSet;
40+
}
41+
42+
intersection(otherSet: Set<T>) {
43+
const intersectionSet = new Set<T>();
44+
45+
const values = this.values();
46+
const otherValues = otherSet.values();
47+
48+
let biggerSet = values;
49+
let smallerSet = otherValues;
50+
51+
if (otherValues.length - values.length > 0) {
52+
biggerSet = otherValues;
53+
smallerSet = values;
54+
}
55+
56+
smallerSet.forEach(value => {
57+
if (biggerSet.includes(value)) {
58+
intersectionSet.add(value);
59+
}
60+
});
61+
62+
return intersectionSet;
63+
}
64+
65+
difference(otherSet: Set<T>) {
66+
const differenceSet = new Set<T>();
67+
68+
this.values().forEach(value => {
69+
if (!otherSet.has(value)) {
70+
differenceSet.add(value);
71+
}
72+
});
73+
74+
return differenceSet;
75+
}
76+
77+
isSubsetOf(otherSet: Set<T>) {
78+
if (this.size() > otherSet.size()) {
79+
return false;
80+
}
81+
82+
let isSubset = true;
83+
this.values().every(value => {
84+
if (!otherSet.has(value)) {
85+
isSubset = false;
86+
return false;
87+
}
88+
return true;
89+
});
90+
91+
return isSubset;
92+
}
93+
94+
isEmpty() {
95+
return this.size() === 0;
96+
}
97+
98+
size() {
99+
return Object.keys(this.items).length;
100+
}
101+
102+
clear() {
103+
this.items = {};
104+
}
105+
106+
toString() {
107+
if (this.isEmpty()) {
108+
return '';
109+
}
110+
const values = this.values();
111+
let objString = `${values[0]}`;
112+
for (let i = 1; i < values.length; i++) {
113+
objString = `${objString},${values[i].toString()}`;
114+
}
115+
return objString;
116+
}
117+
}

‎src/ts/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export { default as DoublyLinkedList } from './data-structures/doubly-linked-lis
55
export { default as CircularLinkedList } from './data-structures/circular-linked-list';
66
export { default as SortedLinkedList } from './data-structures/sorted-linked-list';
77
export { default as StackLinkedList } from './data-structures/stack-linked-list';
8+
export { default as Set } from './data-structures/set';
89

910
export const util = _util;
1011

‎test/js/data-structures/set.spec.js

+352
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import { Set } from '../../../src/js/index';
4+
import MyObj from './my-obj';
5+
6+
describe('Set', () => {
7+
let set;
8+
9+
beforeEach(() => {
10+
set = new Set();
11+
});
12+
13+
it('starts empty', () => {
14+
expect(set.size()).to.equal(0);
15+
expect(set.isEmpty()).to.equal(true);
16+
});
17+
18+
it('adds elements', () => {
19+
for (let i = 1; i < 5; i++) {
20+
set.add(i);
21+
expect(set.size()).to.equal(i);
22+
}
23+
24+
expect(set.isEmpty()).to.equal(false);
25+
});
26+
27+
it('does not allow duplicated elements', () => {
28+
let expected = true;
29+
for (let i = 1; i < 5; i++) {
30+
expect(set.add(i)).to.equal(expected);
31+
}
32+
33+
expected = false;
34+
for (let i = 1; i < 5; i++) {
35+
expect(set.add(i)).to.equal(expected);
36+
}
37+
});
38+
39+
it('deletes elements', () => {
40+
for (let i = 1; i < 5; i++) {
41+
set.add(i);
42+
}
43+
44+
for (let i = 1; i < 5; i++) {
45+
expect(set.delete(i)).to.equal(true);
46+
}
47+
48+
// elements do not exist
49+
for (let i = 1; i < 5; i++) {
50+
expect(set.delete(i)).to.equal(false);
51+
}
52+
53+
expect(set.isEmpty()).to.equal(true);
54+
});
55+
56+
it('returns if element exists', () => {
57+
for (let i = 1; i < 5; i++) {
58+
set.add(i);
59+
expect(set.has(i)).to.equal(true);
60+
}
61+
62+
for (let i = 1; i < 5; i++) {
63+
expect(set.delete(i)).to.equal(true);
64+
expect(set.has(i)).to.equal(false);
65+
}
66+
});
67+
68+
it('returns the correct size', () => {
69+
expect(set.size()).to.equal(0);
70+
71+
for (let i = 1; i < 5; i++) {
72+
set.add(i);
73+
expect(set.size()).to.equal(i);
74+
}
75+
76+
const max = 5;
77+
for (let i = 1; i < max; i++) {
78+
set.delete(i);
79+
expect(set.size()).to.equal(max - i - 1);
80+
}
81+
82+
expect(set.size()).to.equal(0);
83+
expect(set.isEmpty()).to.equal(true);
84+
});
85+
86+
it('returns if it is empty', () => {
87+
expect(set.isEmpty()).to.equal(true);
88+
89+
for (let i = 1; i < 5; i++) {
90+
set.add(i);
91+
expect(set.isEmpty()).to.equal(false);
92+
}
93+
94+
for (let i = 1; i < 5; i++) {
95+
set.delete(i);
96+
expect(set.isEmpty()).to.equal(!(i < 4));
97+
}
98+
99+
expect(set.size()).to.equal(0);
100+
expect(set.isEmpty()).to.equal(true);
101+
});
102+
103+
it('clears the set', () => {
104+
set.clear();
105+
expect(set.isEmpty()).to.equal(true);
106+
107+
set.add(1);
108+
set.add(2);
109+
110+
set.clear();
111+
expect(set.isEmpty()).to.equal(true);
112+
});
113+
114+
function addValues(min, max) {
115+
set = new Set();
116+
117+
for (let i = min; i <= max; i++) {
118+
set.add(i);
119+
}
120+
121+
return set;
122+
}
123+
124+
it('union between empty sets', () => {
125+
const set1 = new Set();
126+
const set2 = new Set();
127+
128+
let setResult = set1.union(set2);
129+
expect(setResult.isEmpty()).to.equal(true);
130+
131+
setResult = set2.union(set1);
132+
expect(setResult.isEmpty()).to.equal(true);
133+
});
134+
135+
it('union between equal sets', () => {
136+
const set1 = addValues(1, 5);
137+
const set2 = addValues(1, 5);
138+
139+
let setResult = set1.union(set2);
140+
for (let i = 1; i <= 5; i++) {
141+
expect(setResult.has(i)).to.equal(true);
142+
}
143+
144+
setResult = set2.union(set1);
145+
for (let i = 1; i <= 5; i++) {
146+
expect(setResult.has(i)).to.equal(true);
147+
}
148+
});
149+
150+
it('union between different sets', () => {
151+
const set1 = addValues(1, 5);
152+
const set2 = addValues(6, 10);
153+
154+
let setResult = set1.union(set2);
155+
for (let i = 1; i <= 10; i++) {
156+
expect(setResult.has(i)).to.equal(true);
157+
}
158+
159+
setResult = set2.union(set1);
160+
for (let i = 1; i <= 10; i++) {
161+
expect(setResult.has(i)).to.equal(true);
162+
}
163+
});
164+
165+
it('union between sets with common values', () => {
166+
const set1 = addValues(1, 5);
167+
const set2 = addValues(3, 6);
168+
169+
let setResult = set1.union(set2);
170+
for (let i = 1; i <= 6; i++) {
171+
expect(setResult.has(i)).to.equal(true);
172+
}
173+
174+
setResult = set2.union(set1);
175+
for (let i = 1; i <= 6; i++) {
176+
expect(setResult.has(i)).to.equal(true);
177+
}
178+
});
179+
180+
it('intersection between empty sets', () => {
181+
const set1 = new Set();
182+
const set2 = new Set();
183+
184+
let setResult = set1.intersection(set2);
185+
expect(setResult.isEmpty()).to.equal(true);
186+
187+
setResult = set2.intersection(set1);
188+
expect(setResult.isEmpty()).to.equal(true);
189+
});
190+
191+
it('intersection between equal sets', () => {
192+
const set1 = addValues(1, 5);
193+
const set2 = addValues(1, 5);
194+
195+
let setResult = set1.intersection(set2);
196+
for (let i = 1; i <= 5; i++) {
197+
expect(setResult.has(i)).to.equal(true);
198+
}
199+
200+
setResult = set2.intersection(set1);
201+
for (let i = 1; i <= 5; i++) {
202+
expect(setResult.has(i)).to.equal(true);
203+
}
204+
});
205+
206+
it('intersection different sets', () => {
207+
const set1 = addValues(1, 5);
208+
const set2 = addValues(6, 10);
209+
210+
let setResult = set1.intersection(set2);
211+
expect(setResult.isEmpty()).to.equal(true);
212+
213+
setResult = set2.intersection(set1);
214+
expect(setResult.isEmpty()).to.equal(true);
215+
});
216+
217+
it('intersection between sets with common values', () => {
218+
const set1 = addValues(1, 5);
219+
const set2 = addValues(3, 6);
220+
221+
let setResult = set1.intersection(set2);
222+
for (let i = 3; i <= 5; i++) {
223+
expect(setResult.has(i)).to.equal(true);
224+
}
225+
226+
setResult = set2.intersection(set1);
227+
for (let i = 3; i <= 5; i++) {
228+
expect(setResult.has(i)).to.equal(true);
229+
}
230+
});
231+
232+
it('difference between empty sets', () => {
233+
const set1 = new Set();
234+
const set2 = new Set();
235+
236+
let setResult = set1.difference(set2);
237+
expect(setResult.isEmpty()).to.equal(true);
238+
239+
setResult = set2.difference(set1);
240+
expect(setResult.isEmpty()).to.equal(true);
241+
});
242+
243+
it('difference between equal sets', () => {
244+
const set1 = addValues(1, 5);
245+
const set2 = addValues(1, 5);
246+
247+
let setResult = set1.difference(set2);
248+
expect(setResult.isEmpty()).to.equal(true);
249+
250+
setResult = set2.difference(set1);
251+
expect(setResult.isEmpty()).to.equal(true);
252+
});
253+
254+
it('difference different sets', () => {
255+
const set1 = addValues(1, 5);
256+
const set2 = addValues(6, 10);
257+
258+
let setResult = set1.difference(set2);
259+
for (let i = 1; i <= 5; i++) {
260+
expect(setResult.has(i)).to.equal(true);
261+
}
262+
263+
setResult = set2.difference(set1);
264+
for (let i = 6; i <= 10; i++) {
265+
expect(setResult.has(i)).to.equal(true);
266+
}
267+
});
268+
269+
it('difference between sets with common values', () => {
270+
const set1 = addValues(1, 5);
271+
const set2 = addValues(3, 6);
272+
273+
let setResult = set1.difference(set2);
274+
for (let i = 1; i <= 2; i++) {
275+
expect(setResult.has(i)).to.equal(true);
276+
}
277+
278+
setResult = set2.difference(set1);
279+
for (let i = 6; i <= 6; i++) {
280+
expect(setResult.has(i)).to.equal(true);
281+
}
282+
});
283+
284+
it('isSubsetOf between empty sets', () => {
285+
const set1 = new Set();
286+
const set2 = new Set();
287+
288+
expect(set1.isSubsetOf(set2)).to.equal(true);
289+
expect(set2.isSubsetOf(set1)).to.equal(true);
290+
});
291+
292+
it('isSubsetOf between equal sets', () => {
293+
const set1 = addValues(1, 5);
294+
const set2 = addValues(1, 5);
295+
296+
expect(set1.isSubsetOf(set2)).to.equal(true);
297+
expect(set2.isSubsetOf(set1)).to.equal(true);
298+
});
299+
300+
it('isSubsetOf different sets', () => {
301+
const set1 = addValues(1, 5);
302+
const set2 = addValues(6, 10);
303+
304+
expect(set1.isSubsetOf(set2)).to.equal(false);
305+
expect(set2.isSubsetOf(set1)).to.equal(false);
306+
});
307+
308+
it('isSubsetOf between sets with common values', () => {
309+
const set1 = addValues(1, 8);
310+
const set2 = addValues(3, 6);
311+
expect(set1.isSubsetOf(set2)).to.equal(false);
312+
expect(set2.isSubsetOf(set1)).to.equal(true);
313+
314+
const set3 = addValues(1, 5);
315+
const set4 = addValues(3, 6);
316+
expect(set3.isSubsetOf(set4)).to.equal(false);
317+
expect(set4.isSubsetOf(set3)).to.equal(false);
318+
});
319+
320+
it('returns toString primitive types', () => {
321+
expect(set.toString()).to.equal('');
322+
323+
set.add(1);
324+
expect(set.toString()).to.equal('1');
325+
326+
set.add(2);
327+
expect(set.toString()).to.equal('1,2');
328+
329+
set.clear();
330+
expect(set.toString()).to.equal('');
331+
});
332+
333+
it('returns toString primitive types: string', () => {
334+
const ds = new Set();
335+
ds.add('el1');
336+
expect(ds.toString()).to.equal('el1');
337+
338+
ds.add('el2');
339+
expect(ds.toString()).to.equal('el1,el2');
340+
});
341+
342+
it('returns toString objects', () => {
343+
const ds = new Set();
344+
expect(ds.toString()).to.equal('');
345+
346+
ds.add(new MyObj(1, 2));
347+
expect(ds.toString()).to.equal('1|2');
348+
349+
ds.add(new MyObj(3, 4));
350+
expect(ds.toString()).to.equal('1|2,3|4');
351+
});
352+
});

‎test/ts/data-structures/set.spec.ts

+352
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import { Set } from '../../../src/ts/index';
4+
import MyObj from './my-obj';
5+
6+
describe('Set', () => {
7+
let set: Set<number>;
8+
9+
beforeEach(() => {
10+
set = new Set<number>();
11+
});
12+
13+
it('starts empty', () => {
14+
expect(set.size()).to.equal(0);
15+
expect(set.isEmpty()).to.equal(true);
16+
});
17+
18+
it('adds elements', () => {
19+
for (let i = 1; i < 5; i++) {
20+
set.add(i);
21+
expect(set.size()).to.equal(i);
22+
}
23+
24+
expect(set.isEmpty()).to.equal(false);
25+
});
26+
27+
it('does not allow duplicated elements', () => {
28+
let expected = true;
29+
for (let i = 1; i < 5; i++) {
30+
expect(set.add(i)).to.equal(expected);
31+
}
32+
33+
expected = false;
34+
for (let i = 1; i < 5; i++) {
35+
expect(set.add(i)).to.equal(expected);
36+
}
37+
});
38+
39+
it('deletes elements', () => {
40+
for (let i = 1; i < 5; i++) {
41+
set.add(i);
42+
}
43+
44+
for (let i = 1; i < 5; i++) {
45+
expect(set.delete(i)).to.equal(true);
46+
}
47+
48+
// elements do not exist
49+
for (let i = 1; i < 5; i++) {
50+
expect(set.delete(i)).to.equal(false);
51+
}
52+
53+
expect(set.isEmpty()).to.equal(true);
54+
});
55+
56+
it('returns if element exists', () => {
57+
for (let i = 1; i < 5; i++) {
58+
set.add(i);
59+
expect(set.has(i)).to.equal(true);
60+
}
61+
62+
for (let i = 1; i < 5; i++) {
63+
expect(set.delete(i)).to.equal(true);
64+
expect(set.has(i)).to.equal(false);
65+
}
66+
});
67+
68+
it('returns the correct size', () => {
69+
expect(set.size()).to.equal(0);
70+
71+
for (let i = 1; i < 5; i++) {
72+
set.add(i);
73+
expect(set.size()).to.equal(i);
74+
}
75+
76+
const max = 5;
77+
for (let i = 1; i < max; i++) {
78+
set.delete(i);
79+
expect(set.size()).to.equal(max - i - 1);
80+
}
81+
82+
expect(set.size()).to.equal(0);
83+
expect(set.isEmpty()).to.equal(true);
84+
});
85+
86+
it('returns if it is empty', () => {
87+
expect(set.isEmpty()).to.equal(true);
88+
89+
for (let i = 1; i < 5; i++) {
90+
set.add(i);
91+
expect(set.isEmpty()).to.equal(false);
92+
}
93+
94+
for (let i = 1; i < 5; i++) {
95+
set.delete(i);
96+
expect(set.isEmpty()).to.equal(!(i < 4));
97+
}
98+
99+
expect(set.size()).to.equal(0);
100+
expect(set.isEmpty()).to.equal(true);
101+
});
102+
103+
it('clears the set', () => {
104+
set.clear();
105+
expect(set.isEmpty()).to.equal(true);
106+
107+
set.add(1);
108+
set.add(2);
109+
110+
set.clear();
111+
expect(set.isEmpty()).to.equal(true);
112+
});
113+
114+
function addValues(min: number, max: number) {
115+
set = new Set();
116+
117+
for (let i = min; i <= max; i++) {
118+
set.add(i);
119+
}
120+
121+
return set;
122+
}
123+
124+
it('union between empty sets', () => {
125+
const set1 = new Set();
126+
const set2 = new Set();
127+
128+
let setResult = set1.union(set2);
129+
expect(setResult.isEmpty()).to.equal(true);
130+
131+
setResult = set2.union(set1);
132+
expect(setResult.isEmpty()).to.equal(true);
133+
});
134+
135+
it('union between equal sets', () => {
136+
const set1 = addValues(1, 5);
137+
const set2 = addValues(1, 5);
138+
139+
let setResult = set1.union(set2);
140+
for (let i = 1; i <= 5; i++) {
141+
expect(setResult.has(i)).to.equal(true);
142+
}
143+
144+
setResult = set2.union(set1);
145+
for (let i = 1; i <= 5; i++) {
146+
expect(setResult.has(i)).to.equal(true);
147+
}
148+
});
149+
150+
it('union between different sets', () => {
151+
const set1 = addValues(1, 5);
152+
const set2 = addValues(6, 10);
153+
154+
let setResult = set1.union(set2);
155+
for (let i = 1; i <= 10; i++) {
156+
expect(setResult.has(i)).to.equal(true);
157+
}
158+
159+
setResult = set2.union(set1);
160+
for (let i = 1; i <= 10; i++) {
161+
expect(setResult.has(i)).to.equal(true);
162+
}
163+
});
164+
165+
it('union between sets with common values', () => {
166+
const set1 = addValues(1, 5);
167+
const set2 = addValues(3, 6);
168+
169+
let setResult = set1.union(set2);
170+
for (let i = 1; i <= 6; i++) {
171+
expect(setResult.has(i)).to.equal(true);
172+
}
173+
174+
setResult = set2.union(set1);
175+
for (let i = 1; i <= 6; i++) {
176+
expect(setResult.has(i)).to.equal(true);
177+
}
178+
});
179+
180+
it('intersection between empty sets', () => {
181+
const set1 = new Set();
182+
const set2 = new Set();
183+
184+
let setResult = set1.intersection(set2);
185+
expect(setResult.isEmpty()).to.equal(true);
186+
187+
setResult = set2.intersection(set1);
188+
expect(setResult.isEmpty()).to.equal(true);
189+
});
190+
191+
it('intersection between equal sets', () => {
192+
const set1 = addValues(1, 5);
193+
const set2 = addValues(1, 5);
194+
195+
let setResult = set1.intersection(set2);
196+
for (let i = 1; i <= 5; i++) {
197+
expect(setResult.has(i)).to.equal(true);
198+
}
199+
200+
setResult = set2.intersection(set1);
201+
for (let i = 1; i <= 5; i++) {
202+
expect(setResult.has(i)).to.equal(true);
203+
}
204+
});
205+
206+
it('intersection different sets', () => {
207+
const set1 = addValues(1, 5);
208+
const set2 = addValues(6, 10);
209+
210+
let setResult = set1.intersection(set2);
211+
expect(setResult.isEmpty()).to.equal(true);
212+
213+
setResult = set2.intersection(set1);
214+
expect(setResult.isEmpty()).to.equal(true);
215+
});
216+
217+
it('intersection between sets with common values', () => {
218+
const set1 = addValues(1, 5);
219+
const set2 = addValues(3, 6);
220+
221+
let setResult = set1.intersection(set2);
222+
for (let i = 3; i <= 5; i++) {
223+
expect(setResult.has(i)).to.equal(true);
224+
}
225+
226+
setResult = set2.intersection(set1);
227+
for (let i = 3; i <= 5; i++) {
228+
expect(setResult.has(i)).to.equal(true);
229+
}
230+
});
231+
232+
it('difference between empty sets', () => {
233+
const set1 = new Set();
234+
const set2 = new Set();
235+
236+
let setResult = set1.difference(set2);
237+
expect(setResult.isEmpty()).to.equal(true);
238+
239+
setResult = set2.difference(set1);
240+
expect(setResult.isEmpty()).to.equal(true);
241+
});
242+
243+
it('difference between equal sets', () => {
244+
const set1 = addValues(1, 5);
245+
const set2 = addValues(1, 5);
246+
247+
let setResult = set1.difference(set2);
248+
expect(setResult.isEmpty()).to.equal(true);
249+
250+
setResult = set2.difference(set1);
251+
expect(setResult.isEmpty()).to.equal(true);
252+
});
253+
254+
it('difference different sets', () => {
255+
const set1 = addValues(1, 5);
256+
const set2 = addValues(6, 10);
257+
258+
let setResult = set1.difference(set2);
259+
for (let i = 1; i <= 5; i++) {
260+
expect(setResult.has(i)).to.equal(true);
261+
}
262+
263+
setResult = set2.difference(set1);
264+
for (let i = 6; i <= 10; i++) {
265+
expect(setResult.has(i)).to.equal(true);
266+
}
267+
});
268+
269+
it('difference between sets with common values', () => {
270+
const set1 = addValues(1, 5);
271+
const set2 = addValues(3, 6);
272+
273+
let setResult = set1.difference(set2);
274+
for (let i = 1; i <= 2; i++) {
275+
expect(setResult.has(i)).to.equal(true);
276+
}
277+
278+
setResult = set2.difference(set1);
279+
for (let i = 6; i <= 6; i++) {
280+
expect(setResult.has(i)).to.equal(true);
281+
}
282+
});
283+
284+
it('isSubsetOf between empty sets', () => {
285+
const set1 = new Set();
286+
const set2 = new Set();
287+
288+
expect(set1.isSubsetOf(set2)).to.equal(true);
289+
expect(set2.isSubsetOf(set1)).to.equal(true);
290+
});
291+
292+
it('isSubsetOf between equal sets', () => {
293+
const set1 = addValues(1, 5);
294+
const set2 = addValues(1, 5);
295+
296+
expect(set1.isSubsetOf(set2)).to.equal(true);
297+
expect(set2.isSubsetOf(set1)).to.equal(true);
298+
});
299+
300+
it('isSubsetOf different sets', () => {
301+
const set1 = addValues(1, 5);
302+
const set2 = addValues(6, 10);
303+
304+
expect(set1.isSubsetOf(set2)).to.equal(false);
305+
expect(set2.isSubsetOf(set1)).to.equal(false);
306+
});
307+
308+
it('isSubsetOf between sets with common values', () => {
309+
const set1 = addValues(1, 8);
310+
const set2 = addValues(3, 6);
311+
expect(set1.isSubsetOf(set2)).to.equal(false);
312+
expect(set2.isSubsetOf(set1)).to.equal(true);
313+
314+
const set3 = addValues(1, 5);
315+
const set4 = addValues(3, 6);
316+
expect(set3.isSubsetOf(set4)).to.equal(false);
317+
expect(set4.isSubsetOf(set3)).to.equal(false);
318+
});
319+
320+
it('returns toString primitive types', () => {
321+
expect(set.toString()).to.equal('');
322+
323+
set.add(1);
324+
expect(set.toString()).to.equal('1');
325+
326+
set.add(2);
327+
expect(set.toString()).to.equal('1,2');
328+
329+
set.clear();
330+
expect(set.toString()).to.equal('');
331+
});
332+
333+
it('returns toString primitive types: string', () => {
334+
const ds = new Set<string>();
335+
ds.add('el1');
336+
expect(ds.toString()).to.equal('el1');
337+
338+
ds.add('el2');
339+
expect(ds.toString()).to.equal('el1,el2');
340+
});
341+
342+
it('returns toString objects', () => {
343+
const ds = new Set<MyObj>();
344+
expect(ds.toString()).to.equal('');
345+
346+
ds.add(new MyObj(1, 2));
347+
expect(ds.toString()).to.equal('1|2');
348+
349+
ds.add(new MyObj(3, 4));
350+
expect(ds.toString()).to.equal('1|2,3|4');
351+
});
352+
});

0 commit comments

Comments
 (0)
Please sign in to comment.