data-structure-typed 1.50.1 → 1.50.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -1
- package/README.md +26 -26
- package/benchmark/report.html +13 -13
- package/benchmark/report.json +153 -159
- package/dist/cjs/data-structures/base/iterable-base.d.ts +114 -9
- package/dist/cjs/data-structures/base/iterable-base.js +143 -7
- package/dist/cjs/data-structures/base/iterable-base.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +43 -46
- package/dist/cjs/data-structures/binary-tree/avl-tree.js +68 -71
- package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +244 -199
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +484 -376
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +54 -74
- package/dist/cjs/data-structures/binary-tree/bst.js +30 -71
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +78 -60
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +84 -89
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multimap.d.ts +37 -56
- package/dist/cjs/data-structures/binary-tree/tree-multimap.js +64 -85
- package/dist/cjs/data-structures/binary-tree/tree-multimap.js.map +1 -1
- package/dist/cjs/data-structures/graph/abstract-graph.d.ts +1 -0
- package/dist/cjs/data-structures/graph/abstract-graph.js +3 -0
- package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/directed-graph.d.ts +14 -0
- package/dist/cjs/data-structures/graph/directed-graph.js +26 -0
- package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/map-graph.d.ts +8 -0
- package/dist/cjs/data-structures/graph/map-graph.js +14 -0
- package/dist/cjs/data-structures/graph/map-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/undirected-graph.d.ts +16 -0
- package/dist/cjs/data-structures/graph/undirected-graph.js +25 -0
- package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
- package/dist/cjs/data-structures/hash/hash-map.d.ts +121 -15
- package/dist/cjs/data-structures/hash/hash-map.js +160 -25
- package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
- package/dist/cjs/data-structures/heap/heap.d.ts +66 -6
- package/dist/cjs/data-structures/heap/heap.js +66 -6
- package/dist/cjs/data-structures/heap/heap.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +67 -50
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +70 -64
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +128 -103
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js +130 -112
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/skip-linked-list.d.ts +63 -36
- package/dist/cjs/data-structures/linked-list/skip-linked-list.js +63 -36
- package/dist/cjs/data-structures/linked-list/skip-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/matrix/matrix.d.ts +35 -4
- package/dist/cjs/data-structures/matrix/matrix.js +50 -11
- package/dist/cjs/data-structures/matrix/matrix.js.map +1 -1
- package/dist/cjs/data-structures/queue/deque.d.ts +49 -19
- package/dist/cjs/data-structures/queue/deque.js +101 -47
- package/dist/cjs/data-structures/queue/deque.js.map +1 -1
- package/dist/cjs/data-structures/queue/queue.d.ts +39 -5
- package/dist/cjs/data-structures/queue/queue.js +47 -5
- package/dist/cjs/data-structures/queue/queue.js.map +1 -1
- package/dist/cjs/data-structures/stack/stack.d.ts +16 -0
- package/dist/cjs/data-structures/stack/stack.js +22 -0
- package/dist/cjs/data-structures/stack/stack.js.map +1 -1
- package/dist/cjs/data-structures/trie/trie.d.ts +38 -1
- package/dist/cjs/data-structures/trie/trie.js +41 -0
- package/dist/cjs/data-structures/trie/trie.js.map +1 -1
- package/dist/cjs/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/cjs/types/data-structures/hash/hash-map.d.ts +4 -3
- package/dist/cjs/types/utils/utils.d.ts +1 -0
- package/dist/mjs/data-structures/base/iterable-base.d.ts +114 -9
- package/dist/mjs/data-structures/base/iterable-base.js +143 -7
- package/dist/mjs/data-structures/binary-tree/avl-tree.d.ts +43 -46
- package/dist/mjs/data-structures/binary-tree/avl-tree.js +68 -71
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +244 -199
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +483 -375
- package/dist/mjs/data-structures/binary-tree/bst.d.ts +54 -74
- package/dist/mjs/data-structures/binary-tree/bst.js +30 -71
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +78 -60
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +84 -89
- package/dist/mjs/data-structures/binary-tree/tree-multimap.d.ts +37 -56
- package/dist/mjs/data-structures/binary-tree/tree-multimap.js +64 -85
- package/dist/mjs/data-structures/graph/abstract-graph.d.ts +1 -0
- package/dist/mjs/data-structures/graph/abstract-graph.js +3 -0
- package/dist/mjs/data-structures/graph/directed-graph.d.ts +14 -0
- package/dist/mjs/data-structures/graph/directed-graph.js +26 -0
- package/dist/mjs/data-structures/graph/map-graph.d.ts +8 -0
- package/dist/mjs/data-structures/graph/map-graph.js +14 -0
- package/dist/mjs/data-structures/graph/undirected-graph.d.ts +16 -0
- package/dist/mjs/data-structures/graph/undirected-graph.js +25 -0
- package/dist/mjs/data-structures/hash/hash-map.d.ts +121 -15
- package/dist/mjs/data-structures/hash/hash-map.js +160 -25
- package/dist/mjs/data-structures/heap/heap.d.ts +66 -6
- package/dist/mjs/data-structures/heap/heap.js +66 -6
- package/dist/mjs/data-structures/linked-list/doubly-linked-list.d.ts +67 -50
- package/dist/mjs/data-structures/linked-list/doubly-linked-list.js +70 -64
- package/dist/mjs/data-structures/linked-list/singly-linked-list.d.ts +128 -103
- package/dist/mjs/data-structures/linked-list/singly-linked-list.js +130 -112
- package/dist/mjs/data-structures/linked-list/skip-linked-list.d.ts +63 -36
- package/dist/mjs/data-structures/linked-list/skip-linked-list.js +63 -36
- package/dist/mjs/data-structures/matrix/matrix.d.ts +35 -4
- package/dist/mjs/data-structures/matrix/matrix.js +50 -11
- package/dist/mjs/data-structures/queue/deque.d.ts +49 -19
- package/dist/mjs/data-structures/queue/deque.js +101 -47
- package/dist/mjs/data-structures/queue/queue.d.ts +39 -5
- package/dist/mjs/data-structures/queue/queue.js +47 -5
- package/dist/mjs/data-structures/stack/stack.d.ts +16 -0
- package/dist/mjs/data-structures/stack/stack.js +22 -0
- package/dist/mjs/data-structures/trie/trie.d.ts +38 -1
- package/dist/mjs/data-structures/trie/trie.js +41 -0
- package/dist/mjs/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/mjs/types/data-structures/hash/hash-map.d.ts +4 -3
- package/dist/mjs/types/utils/utils.d.ts +1 -0
- package/dist/umd/data-structure-typed.js +1730 -1042
- package/dist/umd/data-structure-typed.min.js +3 -3
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +8 -3
- package/src/data-structures/base/iterable-base.ts +172 -19
- package/src/data-structures/binary-tree/avl-tree.ts +97 -97
- package/src/data-structures/binary-tree/binary-tree.ts +674 -671
- package/src/data-structures/binary-tree/bst.ts +89 -131
- package/src/data-structures/binary-tree/rb-tree.ts +127 -155
- package/src/data-structures/binary-tree/tree-multimap.ts +96 -112
- package/src/data-structures/graph/abstract-graph.ts +4 -0
- package/src/data-structures/graph/directed-graph.ts +30 -0
- package/src/data-structures/graph/map-graph.ts +15 -0
- package/src/data-structures/graph/undirected-graph.ts +28 -0
- package/src/data-structures/hash/hash-map.ts +175 -34
- package/src/data-structures/heap/heap.ts +66 -6
- package/src/data-structures/linked-list/doubly-linked-list.ts +72 -66
- package/src/data-structures/linked-list/singly-linked-list.ts +132 -114
- package/src/data-structures/linked-list/skip-linked-list.ts +63 -37
- package/src/data-structures/matrix/matrix.ts +52 -12
- package/src/data-structures/queue/deque.ts +108 -49
- package/src/data-structures/queue/queue.ts +51 -5
- package/src/data-structures/stack/stack.ts +24 -0
- package/src/data-structures/trie/trie.ts +45 -1
- package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
- package/src/types/data-structures/hash/hash-map.ts +4 -3
- package/src/types/utils/utils.ts +2 -0
- package/test/performance/data-structures/graph/directed-graph.test.ts +3 -3
- package/test/performance/data-structures/queue/deque.test.ts +26 -25
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +37 -0
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +46 -17
- package/test/unit/data-structures/binary-tree/bst.test.ts +65 -1
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +38 -1
- package/test/unit/data-structures/binary-tree/tree-multimap.test.ts +37 -32
- package/test/unit/data-structures/graph/abstract-graph.test.ts +8 -0
- package/test/unit/data-structures/graph/directed-graph.test.ts +249 -0
- package/test/unit/data-structures/hash/hash-map.test.ts +376 -353
- package/test/unit/data-structures/heap/heap.test.ts +18 -1
- package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +24 -5
- package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +20 -2
- package/test/unit/data-structures/linked-list/skip-list.test.ts +1 -1
- package/test/unit/data-structures/queue/deque.test.ts +65 -5
- package/test/unit/data-structures/queue/queue.test.ts +22 -5
- package/test/unit/data-structures/stack/stack.test.ts +17 -0
- package/test/unit/data-structures/trie/trie.test.ts +17 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { HashMap, LinkedHashMap } from '../../../../src';
|
|
2
2
|
import { getRandomInt, getRandomIntArray } from '../../../utils';
|
|
3
3
|
|
|
4
|
-
describe('HashMap
|
|
4
|
+
describe('HashMap', () => {
|
|
5
5
|
let hashMap: HashMap<string, number>;
|
|
6
6
|
|
|
7
7
|
beforeEach(() => {
|
|
@@ -84,335 +84,256 @@ describe('HashMap Test1', () => {
|
|
|
84
84
|
// Make sure they are stored separately.
|
|
85
85
|
// expect(hashMap.table[0].length).toBe(2);
|
|
86
86
|
});
|
|
87
|
-
});
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
it('should clone', () => {
|
|
89
|
+
hashMap = new HashMap<string, number>();
|
|
91
90
|
|
|
92
|
-
|
|
93
|
-
hashMap
|
|
94
|
-
|
|
91
|
+
hashMap.set('one', 1);
|
|
92
|
+
hashMap.set('two', 2);
|
|
93
|
+
for (let i = 3; i <= 100; i++) {
|
|
94
|
+
hashMap.set(i.toString(), i);
|
|
95
|
+
}
|
|
95
96
|
|
|
96
|
-
|
|
97
|
-
expect(hashMap.
|
|
98
|
-
|
|
97
|
+
expect(hashMap.get('one')).toBe(1);
|
|
98
|
+
expect(hashMap.get('two')).toBe(2);
|
|
99
|
+
expect(hashMap.get('86')).toBe(86);
|
|
100
|
+
expect(hashMap.size).toBe(100);
|
|
101
|
+
hashMap.delete('two');
|
|
102
|
+
expect(hashMap.size).toBe(99);
|
|
99
103
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
expect(
|
|
104
|
+
const cloned = hashMap.clone();
|
|
105
|
+
expect(cloned.get('one')).toBe(1);
|
|
106
|
+
expect(cloned.get('two')).toBe(undefined);
|
|
107
|
+
expect(cloned.get('86')).toBe(86);
|
|
108
|
+
expect(cloned.size).toBe(99);
|
|
103
109
|
});
|
|
104
110
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
hashMap.set(keyObj, 'objectValue');
|
|
108
|
-
expect(hashMap.get(keyObj)).toBe('objectValue');
|
|
109
|
-
});
|
|
111
|
+
describe('HashMap Test2', () => {
|
|
112
|
+
let hashMap: HashMap;
|
|
110
113
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
beforeEach(() => {
|
|
115
|
+
hashMap = new HashMap();
|
|
116
|
+
});
|
|
114
117
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
hashFn?: (key: K) => string;
|
|
119
|
-
someOtherParam: string;
|
|
120
|
-
}
|
|
121
|
-
) {
|
|
122
|
-
const { someOtherParam, ...restOptions } = options || {};
|
|
123
|
-
super(elements, restOptions);
|
|
124
|
-
this.someOtherParam = someOtherParam;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
118
|
+
it('should create an empty map', () => {
|
|
119
|
+
expect(hashMap.size).toBe(0);
|
|
120
|
+
});
|
|
127
121
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
122
|
+
it('should add a key-value pair', () => {
|
|
123
|
+
hashMap.set('key1', 'value1');
|
|
124
|
+
expect(hashMap.get('key1')).toBe('value1');
|
|
125
|
+
});
|
|
132
126
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
];
|
|
138
|
-
const hm = new HashMap<number, string, { id: number; name: string }>(rawCollection, {
|
|
139
|
-
toEntryFn: rawElement => [rawElement.id, rawElement.name]
|
|
127
|
+
it('should handle object keys correctly', () => {
|
|
128
|
+
const keyObj = { id: 1 };
|
|
129
|
+
hashMap.set(keyObj, 'objectValue');
|
|
130
|
+
expect(hashMap.get(keyObj)).toBe('objectValue');
|
|
140
131
|
});
|
|
141
132
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
133
|
+
test('Inheritability test', () => {
|
|
134
|
+
class ExtendedHashMap<K, V> extends HashMap<K, V> {
|
|
135
|
+
someOtherParam?: string;
|
|
136
|
+
|
|
137
|
+
constructor(
|
|
138
|
+
elements: Iterable<[K, V]> = [],
|
|
139
|
+
options?: {
|
|
140
|
+
hashFn?: (key: K) => string;
|
|
141
|
+
someOtherParam: string;
|
|
142
|
+
}
|
|
143
|
+
) {
|
|
144
|
+
const { someOtherParam, ...restOptions } = options || {};
|
|
145
|
+
super(elements, restOptions);
|
|
146
|
+
this.someOtherParam = someOtherParam;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
146
149
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
});
|
|
150
|
+
const eHM = new ExtendedHashMap<string, number>([], { someOtherParam: 'someOtherParam' });
|
|
151
|
+
eHM.set('one', 1);
|
|
152
|
+
expect(eHM.get('one')).toBe(1);
|
|
153
|
+
});
|
|
152
154
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
155
|
+
test('should raw elements toEntry', () => {
|
|
156
|
+
const rawCollection = [
|
|
157
|
+
{ id: 1, name: 'item 1' },
|
|
158
|
+
{ id: 2, name: 'item 2' }
|
|
159
|
+
];
|
|
160
|
+
const hm = new HashMap<number, string, { id: number; name: string }>(rawCollection, {
|
|
161
|
+
toEntryFn: rawElement => [rawElement.id, rawElement.name]
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
expect(hm.has(1)).toBe(true);
|
|
165
|
+
expect(hm.get(2)).toBe('item 2');
|
|
166
|
+
expect(hm.size).toBe(2);
|
|
167
|
+
});
|
|
156
168
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
169
|
+
it('should update the value for an existing key', () => {
|
|
170
|
+
hashMap.set('key1', 'value1');
|
|
171
|
+
hashMap.set('key1', 'newValue');
|
|
172
|
+
expect(hashMap.get('key1')).toBe('newValue');
|
|
173
|
+
});
|
|
162
174
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
175
|
+
it('should return undefined for a non-existent key', () => {
|
|
176
|
+
expect(hashMap.get('nonExistentKey')).toBeUndefined();
|
|
177
|
+
});
|
|
166
178
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
179
|
+
it('should remove a key-value pair', () => {
|
|
180
|
+
hashMap.set('key1', 'value1');
|
|
181
|
+
hashMap.delete('key1');
|
|
182
|
+
expect(hashMap.get('key1')).toBeUndefined();
|
|
183
|
+
});
|
|
170
184
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const values = [];
|
|
175
|
-
for (const value of hashMap) {
|
|
176
|
-
values.push(value);
|
|
177
|
-
}
|
|
178
|
-
expect(values).toEqual([
|
|
179
|
-
['key1', 'value1'],
|
|
180
|
-
['key2', 'value2']
|
|
181
|
-
]);
|
|
182
|
-
});
|
|
185
|
+
it('should clear the map', () => {
|
|
186
|
+
hashMap.set('key1', 'value1');
|
|
187
|
+
expect(hashMap.size).toBe(1);
|
|
183
188
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
stdMap.forEach((value, key) => {
|
|
187
|
-
expect(hashMap.get(key)).toEqual(value);
|
|
189
|
+
hashMap.clear();
|
|
190
|
+
expect(hashMap.size).toBe(0);
|
|
188
191
|
});
|
|
189
|
-
}
|
|
190
192
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
hashMap.set(item, item);
|
|
198
|
-
}
|
|
199
|
-
for (const item of arr) {
|
|
200
|
-
if (Math.random() > 0.6) {
|
|
201
|
-
expect(hashMap.delete(item)).toEqual(stdMap.delete(item));
|
|
193
|
+
it('should iterate over values', () => {
|
|
194
|
+
hashMap.set('key1', 'value1');
|
|
195
|
+
hashMap.set('key2', 'value2');
|
|
196
|
+
const values = [];
|
|
197
|
+
for (const value of hashMap) {
|
|
198
|
+
values.push(value);
|
|
202
199
|
}
|
|
203
|
-
|
|
204
|
-
|
|
200
|
+
expect(values).toEqual([
|
|
201
|
+
['key1', 'value1'],
|
|
202
|
+
['key2', 'value2']
|
|
203
|
+
]);
|
|
204
|
+
});
|
|
205
205
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
206
|
+
function compareHashMaps(hashMap: HashMap<unknown, unknown>, stdMap: Map<unknown, unknown>) {
|
|
207
|
+
expect(hashMap.size).toEqual(stdMap.size);
|
|
208
|
+
stdMap.forEach((value, key) => {
|
|
209
|
+
expect(hashMap.get(key)).toEqual(value);
|
|
210
|
+
});
|
|
209
211
|
}
|
|
210
|
-
compareHashMaps(hashMap, stdMap);
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
212
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const codObjs: [number, number][] = [];
|
|
213
|
+
const stdMap: Map<unknown, unknown> = new Map();
|
|
214
|
+
const arr: number[] = getRandomIntArray(1000, 1, 10000);
|
|
217
215
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
hashMap.set(codObj, i);
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
test('get elements in hash map', () => {
|
|
227
|
-
for (let i = 0; i < 1000; i++) {
|
|
228
|
-
const codObj = codObjs[i];
|
|
229
|
-
if (codObj) {
|
|
230
|
-
expect(hashMap.get(codObj)).toBe(i);
|
|
216
|
+
it('delete test', () => {
|
|
217
|
+
for (const item of arr) {
|
|
218
|
+
stdMap.set(item, item);
|
|
219
|
+
hashMap.set(item, item);
|
|
231
220
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const codObj = codObjs[i];
|
|
239
|
-
if (codObj) hashMap.delete(codObj);
|
|
240
|
-
}
|
|
241
|
-
expect(hashMap.size).toBe(0);
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
describe('HashMap setMany, keys, values', () => {
|
|
246
|
-
const hm: HashMap<number, number> = new HashMap<number, number>();
|
|
247
|
-
|
|
248
|
-
beforeEach(() => {
|
|
249
|
-
hm.clear();
|
|
250
|
-
hm.setMany([
|
|
251
|
-
[2, 2],
|
|
252
|
-
[3, 3],
|
|
253
|
-
[4, 4],
|
|
254
|
-
[5, 5]
|
|
255
|
-
]);
|
|
256
|
-
hm.setMany([
|
|
257
|
-
[2, 2],
|
|
258
|
-
[3, 3],
|
|
259
|
-
[4, 4],
|
|
260
|
-
[6, 6]
|
|
261
|
-
]);
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
test('keys', () => {
|
|
265
|
-
expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6]);
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
test('values', () => {
|
|
269
|
-
expect([...hm.values()]).toEqual([2, 3, 4, 5, 6]);
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
describe('HashMap HOF', () => {
|
|
274
|
-
let hashMap: HashMap;
|
|
275
|
-
|
|
276
|
-
beforeEach(() => {
|
|
277
|
-
hashMap = new HashMap<string, string>();
|
|
278
|
-
hashMap.set('key1', 'value1');
|
|
279
|
-
hashMap.set('key2', 'value2');
|
|
280
|
-
hashMap.set('key3', 'value3');
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
test('every() returns true if all elements match the condition', () => {
|
|
284
|
-
expect(hashMap.every(value => typeof value === 'string')).toBe(true);
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
test('some() returns true if any element matches the condition', () => {
|
|
288
|
-
expect(hashMap.some((value, key) => key === 'key1')).toBe(true);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
test('forEach() should execute a function for each element', () => {
|
|
292
|
-
const mockCallback = jest.fn();
|
|
293
|
-
hashMap.forEach(mockCallback);
|
|
294
|
-
expect(mockCallback.mock.calls.length).toBe(3);
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
test('map() should transform each element', () => {
|
|
298
|
-
const newHashMap = hashMap.map(value => value.toUpperCase());
|
|
299
|
-
expect(newHashMap.get('key1')).toBe('VALUE1');
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
test('filter() should remove elements that do not match the condition', () => {
|
|
303
|
-
const filteredHashMap = hashMap.filter((value, key) => key !== 'key1');
|
|
304
|
-
expect(filteredHashMap.has('key1')).toBe(false);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
test('reduce() should accumulate values', () => {
|
|
308
|
-
const result = hashMap.reduce((acc, value) => acc + value, '');
|
|
309
|
-
expect(result).toBe('value1value2value3');
|
|
310
|
-
});
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
describe('LinkedHashMap Test1', () => {
|
|
314
|
-
let hashMap: LinkedHashMap<string, number>;
|
|
315
|
-
|
|
316
|
-
beforeEach(() => {
|
|
317
|
-
hashMap = new LinkedHashMap<string, number>();
|
|
318
|
-
});
|
|
221
|
+
for (const item of arr) {
|
|
222
|
+
if (Math.random() > 0.6) {
|
|
223
|
+
expect(hashMap.delete(item)).toEqual(stdMap.delete(item));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
compareHashMaps(hashMap, stdMap);
|
|
319
227
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
expect(hashMap.isEmpty()).toBe(true);
|
|
228
|
+
for (let i = 0; i < 1000; ++i) {
|
|
229
|
+
const random = getRandomInt(0, 100);
|
|
230
|
+
expect(hashMap.delete(random)).toEqual(stdMap.delete(random));
|
|
231
|
+
}
|
|
232
|
+
compareHashMaps(hashMap, stdMap);
|
|
233
|
+
});
|
|
327
234
|
});
|
|
328
235
|
|
|
329
|
-
|
|
330
|
-
hashMap
|
|
331
|
-
|
|
332
|
-
hashMap.set('three', 3);
|
|
236
|
+
describe('HashMap for coordinate object keys', () => {
|
|
237
|
+
const hashMap: HashMap<[number, number], number> = new HashMap();
|
|
238
|
+
const codObjs: [number, number][] = [];
|
|
333
239
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
240
|
+
test('set elements in hash map', () => {
|
|
241
|
+
for (let i = 0; i < 1000; i++) {
|
|
242
|
+
const codObj: [number, number] = [getRandomInt(-10000, 10000), i];
|
|
243
|
+
codObjs.push(codObj);
|
|
244
|
+
hashMap.set(codObj, i);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
338
247
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
248
|
+
test('get elements in hash map', () => {
|
|
249
|
+
for (let i = 0; i < 1000; i++) {
|
|
250
|
+
const codObj = codObjs[i];
|
|
251
|
+
if (codObj) {
|
|
252
|
+
expect(hashMap.get(codObj)).toBe(i);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
});
|
|
343
256
|
|
|
344
|
-
|
|
345
|
-
|
|
257
|
+
test('delete elements in hash map', () => {
|
|
258
|
+
for (let i = 0; i < 1000; i++) {
|
|
259
|
+
if (i === 500) expect(hashMap.size).toBe(500);
|
|
260
|
+
const codObj = codObjs[i];
|
|
261
|
+
if (codObj) hashMap.delete(codObj);
|
|
262
|
+
}
|
|
263
|
+
expect(hashMap.size).toBe(0);
|
|
264
|
+
});
|
|
346
265
|
});
|
|
347
266
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
267
|
+
describe('HashMap setMany, keys, values', () => {
|
|
268
|
+
const hm: HashMap<number, number> = new HashMap<number, number>();
|
|
269
|
+
|
|
270
|
+
beforeEach(() => {
|
|
271
|
+
hm.clear();
|
|
272
|
+
hm.setMany([
|
|
273
|
+
[2, 2],
|
|
274
|
+
[3, 3],
|
|
275
|
+
[4, 4],
|
|
276
|
+
[5, 5]
|
|
277
|
+
]);
|
|
278
|
+
hm.setMany([
|
|
279
|
+
[2, 2],
|
|
280
|
+
[3, 3],
|
|
281
|
+
[4, 4],
|
|
282
|
+
[6, 6]
|
|
283
|
+
]);
|
|
284
|
+
});
|
|
356
285
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
286
|
+
test('keys', () => {
|
|
287
|
+
expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6]);
|
|
288
|
+
});
|
|
360
289
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
290
|
+
test('values', () => {
|
|
291
|
+
expect([...hm.values()]).toEqual([2, 3, 4, 5, 6]);
|
|
292
|
+
});
|
|
364
293
|
});
|
|
365
294
|
|
|
366
|
-
|
|
367
|
-
hashMap
|
|
368
|
-
hashMap.set('two', 2);
|
|
369
|
-
hashMap.set('three', 3);
|
|
295
|
+
describe('HashMap HOF', () => {
|
|
296
|
+
let hashMap: HashMap;
|
|
370
297
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
298
|
+
beforeEach(() => {
|
|
299
|
+
hashMap = new HashMap<string, string>();
|
|
300
|
+
hashMap.set('key1', 'value1');
|
|
301
|
+
hashMap.set('key2', 'value2');
|
|
302
|
+
hashMap.set('key3', 'value3');
|
|
303
|
+
});
|
|
376
304
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
305
|
+
test('every() returns true if all elements match the condition', () => {
|
|
306
|
+
expect(hashMap.every(value => typeof value === 'string')).toBe(true);
|
|
307
|
+
});
|
|
380
308
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
hashMap.set('four', 4); // This should trigger a resize
|
|
309
|
+
test('some() returns true if any element matches the condition', () => {
|
|
310
|
+
expect(hashMap.some((value, key) => key === 'key1')).toBe(true);
|
|
311
|
+
});
|
|
385
312
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
});
|
|
313
|
+
test('forEach() should execute a function for each element', () => {
|
|
314
|
+
const mockCallback = jest.fn();
|
|
315
|
+
hashMap.forEach(mockCallback);
|
|
316
|
+
expect(mockCallback.mock.calls.length).toBe(3);
|
|
317
|
+
});
|
|
392
318
|
|
|
393
|
-
|
|
394
|
-
|
|
319
|
+
test('map() should transform each element', () => {
|
|
320
|
+
const newHashMap = hashMap.map(value => value.toUpperCase());
|
|
321
|
+
expect(newHashMap.get('key1')).toBe('VALUE1');
|
|
322
|
+
});
|
|
395
323
|
|
|
396
|
-
|
|
397
|
-
|
|
324
|
+
test('filter() should remove elements that do not match the condition', () => {
|
|
325
|
+
const filteredHashMap = hashMap.filter((value, key) => key !== 'key1');
|
|
326
|
+
expect(filteredHashMap.has('key1')).toBe(false);
|
|
327
|
+
});
|
|
398
328
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
// expect(hashMap.table[0].length).toBe(2);
|
|
329
|
+
test('reduce() should accumulate values', () => {
|
|
330
|
+
const result = hashMap.reduce((acc, value) => acc + value, '');
|
|
331
|
+
expect(result).toBe('value1value2value3');
|
|
332
|
+
});
|
|
404
333
|
});
|
|
405
|
-
|
|
406
|
-
// it('should handle number keys correctly', () => {
|
|
407
|
-
// const hm = new LinkedHashMap();
|
|
408
|
-
// hm.set(999, { a: '999Value' });
|
|
409
|
-
// hm.set('999', {a: '999StrValue'})
|
|
410
|
-
// expect(hm.get(999)).toEqual({ a: '999Value' });
|
|
411
|
-
// expect(hm.get('999')).toEqual({ a: '999StrValue1' });
|
|
412
|
-
// });
|
|
413
334
|
});
|
|
414
335
|
|
|
415
|
-
describe('LinkedHashMap
|
|
336
|
+
describe('LinkedHashMap', () => {
|
|
416
337
|
let hashMap: LinkedHashMap;
|
|
417
338
|
|
|
418
339
|
beforeEach(() => {
|
|
@@ -487,7 +408,7 @@ describe('LinkedHashMap Test2', () => {
|
|
|
487
408
|
expect(hashMap.last).toEqual([key, value]);
|
|
488
409
|
expect(hashMap.reverseBegin().next().value).toEqual([key, value]);
|
|
489
410
|
} else if (index <= 1000) {
|
|
490
|
-
expect(hashMap.
|
|
411
|
+
expect(hashMap.at(index)).toBe(value);
|
|
491
412
|
}
|
|
492
413
|
expect(hashMap.get(key)).toEqual(value);
|
|
493
414
|
index++;
|
|
@@ -536,92 +457,194 @@ describe('LinkedHashMap Test2', () => {
|
|
|
536
457
|
test('should get element at specific index', () => {
|
|
537
458
|
hashMap.set('key1', 'value1');
|
|
538
459
|
hashMap.set('key2', 'value2');
|
|
539
|
-
expect(hashMap.
|
|
460
|
+
expect(hashMap.at(1)).toBe('value2');
|
|
540
461
|
});
|
|
541
|
-
});
|
|
542
462
|
|
|
543
|
-
describe('LinkedHashMap
|
|
544
|
-
|
|
545
|
-
const codObjs: [number, number][] = [];
|
|
463
|
+
describe('LinkedHashMap basic', () => {
|
|
464
|
+
let hashMap: LinkedHashMap<string, number>;
|
|
546
465
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
codObjs.push(codObj);
|
|
551
|
-
hashMap.set(codObj, i);
|
|
552
|
-
}
|
|
553
|
-
});
|
|
466
|
+
beforeEach(() => {
|
|
467
|
+
hashMap = new LinkedHashMap<string, number>();
|
|
468
|
+
});
|
|
554
469
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
470
|
+
it('should initialize correctly', () => {
|
|
471
|
+
expect(hashMap.size).toBe(0);
|
|
472
|
+
// expect(hashMap.table.length).toBe(16);
|
|
473
|
+
// expect(hashMap.loadFactor).toBe(0.75);
|
|
474
|
+
// expect(hashMap.capacityMultiplier).toBe(2);
|
|
475
|
+
// expect(hashMap.initialCapacity).toBe(16);
|
|
476
|
+
expect(hashMap.isEmpty()).toBe(true);
|
|
477
|
+
});
|
|
563
478
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
if (codObj) hashMap.delete(codObj);
|
|
569
|
-
}
|
|
570
|
-
expect(hashMap.size).toBe(0);
|
|
571
|
-
});
|
|
572
|
-
});
|
|
479
|
+
it('should put and get values', () => {
|
|
480
|
+
hashMap.set('one', 1);
|
|
481
|
+
hashMap.set('two', 2);
|
|
482
|
+
hashMap.set('three', 3);
|
|
573
483
|
|
|
574
|
-
|
|
575
|
-
|
|
484
|
+
expect(hashMap.get('one')).toBe(1);
|
|
485
|
+
expect(hashMap.get('two')).toBe(2);
|
|
486
|
+
expect(hashMap.get('three')).toBe(3);
|
|
487
|
+
});
|
|
576
488
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
[3, 3],
|
|
582
|
-
[4, 4],
|
|
583
|
-
[5, 5]
|
|
584
|
-
]);
|
|
585
|
-
hm.setMany([
|
|
586
|
-
[2, 2],
|
|
587
|
-
[3, 3],
|
|
588
|
-
[4, 4],
|
|
589
|
-
[6, 6]
|
|
590
|
-
]);
|
|
591
|
-
});
|
|
489
|
+
it('should handle key collisions', () => {
|
|
490
|
+
// Force a collision by setting two different keys to the same bucket
|
|
491
|
+
hashMap.set('key1', 1);
|
|
492
|
+
hashMap.set('key2', 2);
|
|
592
493
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
494
|
+
expect(hashMap.get('key1')).toBe(1);
|
|
495
|
+
expect(hashMap.get('key2')).toBe(2);
|
|
496
|
+
});
|
|
596
497
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
498
|
+
it('should delete values', () => {
|
|
499
|
+
hashMap.set('one', 1);
|
|
500
|
+
hashMap.set('two', 2);
|
|
600
501
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
[4, 4],
|
|
606
|
-
[5, 5],
|
|
607
|
-
[6, 6]
|
|
608
|
-
]);
|
|
609
|
-
});
|
|
502
|
+
hashMap.delete('one');
|
|
503
|
+
expect(hashMap.get('one')).toBeUndefined();
|
|
504
|
+
expect(hashMap.size).toBe(1);
|
|
505
|
+
});
|
|
610
506
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
507
|
+
it('should clear the LinkedHashMap', () => {
|
|
508
|
+
hashMap.set('one', 1);
|
|
509
|
+
hashMap.set('two', 2);
|
|
510
|
+
|
|
511
|
+
hashMap.clear();
|
|
512
|
+
expect(hashMap.size).toBe(0);
|
|
513
|
+
expect(hashMap.isEmpty()).toBe(true);
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
it('should iterate over entries', () => {
|
|
517
|
+
hashMap.set('one', 1);
|
|
518
|
+
hashMap.set('two', 2);
|
|
519
|
+
hashMap.set('three', 3);
|
|
520
|
+
|
|
521
|
+
// const entries = Array.from(hashMap.entries());
|
|
522
|
+
// expect(entries).toContainEqual(['one', 1]);
|
|
523
|
+
// expect(entries).toContainEqual(['two', 2]);
|
|
524
|
+
// expect(entries).toContainEqual(['three', 3]);
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
it('should resize the table when load factor is exceeded', () => {
|
|
528
|
+
// Set a small initial capacity for testing resizing
|
|
529
|
+
hashMap = new LinkedHashMap<string, number>();
|
|
530
|
+
|
|
531
|
+
hashMap.set('one', 1);
|
|
532
|
+
hashMap.set('two', 2);
|
|
533
|
+
hashMap.set('three', 3);
|
|
534
|
+
hashMap.set('four', 4); // This should trigger a resize
|
|
535
|
+
|
|
536
|
+
// expect(hashMap.table.length).toBe(8);
|
|
537
|
+
expect(hashMap.get('one')).toBe(1);
|
|
538
|
+
expect(hashMap.get('two')).toBe(2);
|
|
539
|
+
expect(hashMap.get('three')).toBe(3);
|
|
540
|
+
expect(hashMap.get('four')).toBe(4);
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
it('should allow using a custom hash function', () => {
|
|
544
|
+
hashMap = new LinkedHashMap<string, number>();
|
|
545
|
+
|
|
546
|
+
hashMap.set('one', 1);
|
|
547
|
+
hashMap.set('two', 2);
|
|
548
|
+
|
|
549
|
+
expect(hashMap.get('one')).toBe(1);
|
|
550
|
+
expect(hashMap.get('two')).toBe(2);
|
|
551
|
+
// Since the custom hash function always returns 0, these keys will collide.
|
|
552
|
+
// Make sure they are stored separately.
|
|
553
|
+
// expect(hashMap.table[0].length).toBe(2);
|
|
554
|
+
});
|
|
614
555
|
|
|
615
|
-
|
|
616
|
-
|
|
556
|
+
// it('should handle number keys correctly', () => {
|
|
557
|
+
// const hm = new LinkedHashMap();
|
|
558
|
+
// hm.set(999, { a: '999Value' });
|
|
559
|
+
// hm.set('999', {a: '999StrValue'})
|
|
560
|
+
// expect(hm.get(999)).toEqual({ a: '999Value' });
|
|
561
|
+
// expect(hm.get('999')).toEqual({ a: '999StrValue1' });
|
|
562
|
+
// });
|
|
617
563
|
});
|
|
618
564
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
565
|
+
describe('coordinate object keys', () => {
|
|
566
|
+
const hashMap: LinkedHashMap<[number, number], number> = new LinkedHashMap();
|
|
567
|
+
const codObjs: [number, number][] = [];
|
|
568
|
+
|
|
569
|
+
test('set elements in hash map', () => {
|
|
570
|
+
for (let i = 0; i < 1000; i++) {
|
|
571
|
+
const codObj: [number, number] = [getRandomInt(-10000, 10000), i];
|
|
572
|
+
codObjs.push(codObj);
|
|
573
|
+
hashMap.set(codObj, i);
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
test('get elements in hash map', () => {
|
|
578
|
+
for (let i = 0; i < 1000; i++) {
|
|
579
|
+
const codObj = codObjs[i];
|
|
580
|
+
if (codObj) {
|
|
581
|
+
expect(hashMap.get(codObj)).toBe(i);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
test('delete elements in hash map', () => {
|
|
587
|
+
for (let i = 0; i < 1000; i++) {
|
|
588
|
+
if (i === 500) expect(hashMap.size).toBe(500);
|
|
589
|
+
const codObj = codObjs[i];
|
|
590
|
+
if (codObj) hashMap.delete(codObj);
|
|
591
|
+
}
|
|
592
|
+
expect(hashMap.size).toBe(0);
|
|
593
|
+
});
|
|
622
594
|
});
|
|
623
595
|
|
|
624
|
-
|
|
625
|
-
|
|
596
|
+
describe('setMany, keys, values', () => {
|
|
597
|
+
const hm: LinkedHashMap<number, number> = new LinkedHashMap<number, number>();
|
|
598
|
+
|
|
599
|
+
beforeEach(() => {
|
|
600
|
+
hm.clear();
|
|
601
|
+
hm.setMany([
|
|
602
|
+
[2, 2],
|
|
603
|
+
[3, 3],
|
|
604
|
+
[4, 4],
|
|
605
|
+
[5, 5]
|
|
606
|
+
]);
|
|
607
|
+
hm.setMany([
|
|
608
|
+
[2, 2],
|
|
609
|
+
[3, 3],
|
|
610
|
+
[4, 4],
|
|
611
|
+
[6, 6]
|
|
612
|
+
]);
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
test('keys', () => {
|
|
616
|
+
expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6]);
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
test('values', () => {
|
|
620
|
+
expect([...hm.values()]).toEqual([2, 3, 4, 5, 6]);
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
test('entries', () => {
|
|
624
|
+
expect([...hm.entries()]).toEqual([
|
|
625
|
+
[2, 2],
|
|
626
|
+
[3, 3],
|
|
627
|
+
[4, 4],
|
|
628
|
+
[5, 5],
|
|
629
|
+
[6, 6]
|
|
630
|
+
]);
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
test('every', () => {
|
|
634
|
+
expect(hm.every(value => value > 4)).toBe(false);
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
test('some', () => {
|
|
638
|
+
expect(hm.some(value => value > 6)).toBe(false);
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
test('hasValue', () => {
|
|
642
|
+
expect(hm.hasValue(3)).toBe(true);
|
|
643
|
+
expect(hm.hasValue(7)).toBe(false);
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
test('print', () => {
|
|
647
|
+
// hm.print();
|
|
648
|
+
});
|
|
626
649
|
});
|
|
627
650
|
});
|