data-structure-typed 1.46.3 → 1.46.4
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 +1 -1
- package/benchmark/report.html +1 -1
- package/benchmark/report.json +5 -17
- package/dist/cjs/data-structures/hash/hash-map.d.ts +22 -26
- package/dist/cjs/data-structures/hash/hash-map.js +105 -76
- package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
- package/dist/cjs/data-structures/hash/index.d.ts +0 -4
- package/dist/cjs/data-structures/hash/index.js +0 -4
- package/dist/cjs/data-structures/hash/index.js.map +1 -1
- package/dist/cjs/types/data-structures/hash/hash-map.d.ts +5 -0
- package/dist/cjs/types/data-structures/hash/index.d.ts +0 -4
- package/dist/cjs/types/data-structures/hash/index.js +0 -4
- package/dist/cjs/types/data-structures/hash/index.js.map +1 -1
- package/dist/cjs/utils/utils.d.ts +1 -1
- package/dist/cjs/utils/utils.js +3 -3
- package/dist/cjs/utils/utils.js.map +1 -1
- package/dist/mjs/data-structures/hash/hash-map.d.ts +22 -26
- package/dist/mjs/data-structures/hash/hash-map.js +108 -77
- package/dist/mjs/data-structures/hash/index.d.ts +0 -4
- package/dist/mjs/data-structures/hash/index.js +0 -4
- package/dist/mjs/types/data-structures/hash/hash-map.d.ts +5 -0
- package/dist/mjs/types/data-structures/hash/index.d.ts +0 -4
- package/dist/mjs/types/data-structures/hash/index.js +0 -4
- package/dist/mjs/utils/utils.d.ts +1 -1
- package/dist/mjs/utils/utils.js +1 -1
- package/dist/umd/data-structure-typed.js +96 -182
- package/dist/umd/data-structure-typed.min.js +1 -1
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +1 -1
- package/src/data-structures/hash/hash-map.ts +131 -81
- package/src/data-structures/hash/index.ts +0 -4
- package/src/types/data-structures/hash/hash-map.ts +6 -0
- package/src/types/data-structures/hash/index.ts +0 -4
- package/src/utils/utils.ts +1 -1
- package/test/performance/data-structures/hash/hash-map.test.ts +75 -0
- package/test/unit/data-structures/hash/hash-map.test.ts +32 -0
- package/dist/cjs/data-structures/hash/coordinate-map.d.ts +0 -44
- package/dist/cjs/data-structures/hash/coordinate-map.js +0 -63
- package/dist/cjs/data-structures/hash/coordinate-map.js.map +0 -1
- package/dist/cjs/data-structures/hash/coordinate-set.d.ts +0 -36
- package/dist/cjs/data-structures/hash/coordinate-set.js +0 -53
- package/dist/cjs/data-structures/hash/coordinate-set.js.map +0 -1
- package/dist/cjs/data-structures/hash/tree-map.d.ts +0 -2
- package/dist/cjs/data-structures/hash/tree-map.js +0 -7
- package/dist/cjs/data-structures/hash/tree-map.js.map +0 -1
- package/dist/cjs/data-structures/hash/tree-set.d.ts +0 -2
- package/dist/cjs/data-structures/hash/tree-set.js +0 -7
- package/dist/cjs/data-structures/hash/tree-set.js.map +0 -1
- package/dist/cjs/types/data-structures/hash/coordinate-map.d.ts +0 -1
- package/dist/cjs/types/data-structures/hash/coordinate-map.js +0 -3
- package/dist/cjs/types/data-structures/hash/coordinate-map.js.map +0 -1
- package/dist/cjs/types/data-structures/hash/coordinate-set.d.ts +0 -1
- package/dist/cjs/types/data-structures/hash/coordinate-set.js +0 -3
- package/dist/cjs/types/data-structures/hash/coordinate-set.js.map +0 -1
- package/dist/cjs/types/data-structures/hash/tree-map.d.ts +0 -1
- package/dist/cjs/types/data-structures/hash/tree-map.js +0 -3
- package/dist/cjs/types/data-structures/hash/tree-map.js.map +0 -1
- package/dist/cjs/types/data-structures/hash/tree-set.d.ts +0 -1
- package/dist/cjs/types/data-structures/hash/tree-set.js +0 -3
- package/dist/cjs/types/data-structures/hash/tree-set.js.map +0 -1
- package/dist/mjs/data-structures/hash/coordinate-map.d.ts +0 -44
- package/dist/mjs/data-structures/hash/coordinate-map.js +0 -58
- package/dist/mjs/data-structures/hash/coordinate-set.d.ts +0 -36
- package/dist/mjs/data-structures/hash/coordinate-set.js +0 -48
- package/dist/mjs/data-structures/hash/tree-map.d.ts +0 -2
- package/dist/mjs/data-structures/hash/tree-map.js +0 -2
- package/dist/mjs/data-structures/hash/tree-set.d.ts +0 -2
- package/dist/mjs/data-structures/hash/tree-set.js +0 -2
- package/dist/mjs/types/data-structures/hash/coordinate-map.d.ts +0 -1
- package/dist/mjs/types/data-structures/hash/coordinate-map.js +0 -1
- package/dist/mjs/types/data-structures/hash/coordinate-set.d.ts +0 -1
- package/dist/mjs/types/data-structures/hash/coordinate-set.js +0 -1
- package/dist/mjs/types/data-structures/hash/tree-map.d.ts +0 -1
- package/dist/mjs/types/data-structures/hash/tree-map.js +0 -1
- package/dist/mjs/types/data-structures/hash/tree-set.d.ts +0 -1
- package/dist/mjs/types/data-structures/hash/tree-set.js +0 -1
- package/src/data-structures/hash/coordinate-map.ts +0 -63
- package/src/data-structures/hash/coordinate-set.ts +0 -52
- package/src/data-structures/hash/tree-map.ts +0 -2
- package/src/data-structures/hash/tree-set.ts +0 -2
- package/src/types/data-structures/hash/coordinate-map.ts +0 -1
- package/src/types/data-structures/hash/coordinate-set.ts +0 -1
- package/src/types/data-structures/hash/tree-map.ts +0 -1
- package/src/types/data-structures/hash/tree-set.ts +0 -1
- package/test/performance/data-structures/hash/coordinate-map.test.ts +0 -0
- package/test/performance/data-structures/hash/coordinate-set.test.ts +0 -0
- package/test/unit/data-structures/hash/coordinate-map.test.ts +0 -74
- package/test/unit/data-structures/hash/coordinate-set.test.ts +0 -66
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-structure-typed",
|
|
3
|
-
"version": "1.46.
|
|
3
|
+
"version": "1.46.4",
|
|
4
4
|
"description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/mjs/index.js",
|
|
@@ -6,31 +6,41 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
import { HashMapLinkedNode,
|
|
9
|
+
import { isWeakKey, rangeCheck } from '../../utils';
|
|
10
|
+
import { HashMapLinkedNode, HashMapOptions } from '../../types';
|
|
11
11
|
|
|
12
12
|
export class HashMap<K = any, V = any> {
|
|
13
|
-
|
|
14
|
-
protected
|
|
15
|
-
protected
|
|
16
|
-
protected _head: HashMapLinkedNode<K, V>;
|
|
17
|
-
protected _tail: HashMapLinkedNode<K, V>;
|
|
18
|
-
protected readonly _sentinel: HashMapLinkedNode<K, V>;
|
|
13
|
+
|
|
14
|
+
protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};
|
|
15
|
+
protected _objMap = new WeakMap<WeakKey, HashMapLinkedNode<K, V | undefined>>();
|
|
16
|
+
protected _head: HashMapLinkedNode<K, V | undefined>;
|
|
17
|
+
protected _tail: HashMapLinkedNode<K, V | undefined>;
|
|
18
|
+
protected readonly _sentinel: HashMapLinkedNode<K, V | undefined>;
|
|
19
|
+
protected _hashFn: (key: K) => string;
|
|
20
|
+
protected _objHashFn: (key: K) => WeakKey;
|
|
19
21
|
|
|
20
22
|
/**
|
|
21
|
-
* The constructor initializes a
|
|
22
|
-
* @param
|
|
23
|
-
*
|
|
24
|
-
* `K` represents the type of the key and `V` represents the
|
|
23
|
+
* The constructor initializes a HashMapLinkedNode with an optional iterable of key-value pairs.
|
|
24
|
+
* @param options - The `options` parameter is an object that contains the `elements` property. The
|
|
25
|
+
* `elements` property is an iterable that contains key-value pairs represented as arrays `[K, V]`.
|
|
25
26
|
*/
|
|
26
|
-
constructor(
|
|
27
|
-
|
|
27
|
+
constructor(options: HashMapOptions<K, V> = {
|
|
28
|
+
elements: [],
|
|
29
|
+
hashFn: (key: K) => String(key),
|
|
30
|
+
objHashFn: (key: K) => (<WeakKey>key)
|
|
31
|
+
}) {
|
|
28
32
|
this._sentinel = <HashMapLinkedNode<K, V>>{};
|
|
29
33
|
this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
const { elements, hashFn, objHashFn } = options;
|
|
36
|
+
this._hashFn = hashFn;
|
|
37
|
+
this._objHashFn = objHashFn;
|
|
38
|
+
if (elements) {
|
|
39
|
+
for (const el of elements) {
|
|
40
|
+
this.set(el[0], el[1]);
|
|
41
|
+
}
|
|
33
42
|
}
|
|
43
|
+
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
protected _size = 0;
|
|
@@ -98,50 +108,54 @@ export class HashMap<K = any, V = any> {
|
|
|
98
108
|
* type, but typically it is a string or symbol.
|
|
99
109
|
* @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the
|
|
100
110
|
* value associated with the key being set in the data structure.
|
|
101
|
-
* @param {boolean} isObjectKey - A boolean flag indicating whether the key is an object key or not.
|
|
102
111
|
* @returns the size of the data structure after the key-value pair has been set.
|
|
103
112
|
*/
|
|
104
|
-
set(key: K, value?: V
|
|
105
|
-
let
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
113
|
+
set(key: K, value?: V) {
|
|
114
|
+
let node;
|
|
115
|
+
|
|
116
|
+
if (isWeakKey(key)) {
|
|
117
|
+
// const hash = this._objHashFn(key);
|
|
118
|
+
const hash = key;
|
|
119
|
+
node = this._objMap.get(hash);
|
|
120
|
+
|
|
121
|
+
if (node) {
|
|
122
|
+
// If the node already exists, update its value
|
|
123
|
+
node.value = value;
|
|
124
|
+
} else {
|
|
125
|
+
// Create new node
|
|
126
|
+
node = { key: <K>hash, value, prev: this._tail, next: this._sentinel };
|
|
127
|
+
|
|
128
|
+
// Add new nodes to _objMap and linked list
|
|
129
|
+
this._objMap.set(hash, node);
|
|
111
130
|
}
|
|
112
|
-
Object.defineProperty(key, this.OBJ_KEY_INDEX, {
|
|
113
|
-
value: this._nodes.length,
|
|
114
|
-
configurable: true
|
|
115
|
-
});
|
|
116
|
-
newTail = {
|
|
117
|
-
key: key,
|
|
118
|
-
value: <V>value,
|
|
119
|
-
prev: this._tail,
|
|
120
|
-
next: this._sentinel
|
|
121
|
-
};
|
|
122
|
-
this._nodes.push(newTail);
|
|
123
131
|
} else {
|
|
124
|
-
const
|
|
132
|
+
const hash = this._hashFn(key);
|
|
133
|
+
// Non-object keys are handled in the same way as the original implementation
|
|
134
|
+
node = this._noObjMap[hash];
|
|
125
135
|
if (node) {
|
|
126
|
-
node.value =
|
|
127
|
-
|
|
136
|
+
node.value = value;
|
|
137
|
+
} else {
|
|
138
|
+
this._noObjMap[hash] = node = {
|
|
139
|
+
key,
|
|
140
|
+
value,
|
|
141
|
+
prev: this._tail,
|
|
142
|
+
next: this._sentinel
|
|
143
|
+
};
|
|
128
144
|
}
|
|
129
|
-
this._orgMap[<string>(<unknown>key)] = newTail = {
|
|
130
|
-
key: key,
|
|
131
|
-
value: <V>value,
|
|
132
|
-
prev: this._tail,
|
|
133
|
-
next: this._sentinel
|
|
134
|
-
};
|
|
135
145
|
}
|
|
146
|
+
|
|
136
147
|
if (this._size === 0) {
|
|
137
|
-
this._head =
|
|
138
|
-
this._sentinel.next =
|
|
148
|
+
this._head = node;
|
|
149
|
+
this._sentinel.next = node;
|
|
139
150
|
} else {
|
|
140
|
-
this._tail.next =
|
|
151
|
+
this._tail.next = node;
|
|
141
152
|
}
|
|
142
|
-
|
|
143
|
-
this.
|
|
144
|
-
|
|
153
|
+
|
|
154
|
+
this._tail = node;
|
|
155
|
+
this._sentinel.prev = node;
|
|
156
|
+
this._size++;
|
|
157
|
+
|
|
158
|
+
return this._size;
|
|
145
159
|
}
|
|
146
160
|
|
|
147
161
|
/**
|
|
@@ -152,21 +166,21 @@ export class HashMap<K = any, V = any> {
|
|
|
152
166
|
* key directly or by using an index stored in the key object.
|
|
153
167
|
* @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be
|
|
154
168
|
* of any type, but typically it is a string or symbol.
|
|
155
|
-
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
|
|
156
|
-
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that
|
|
157
|
-
* `key` is an object key. If `isObjectKey` is `false`, it means that `key`
|
|
158
169
|
* @returns The value associated with the given key is being returned. If the key is an object key,
|
|
159
170
|
* the value is retrieved from the `_nodes` array using the index stored in the `OBJ_KEY_INDEX`
|
|
160
|
-
* property of the key. If the key is a string key, the value is retrieved from the `
|
|
171
|
+
* property of the key. If the key is a string key, the value is retrieved from the `_noObjMap` object
|
|
161
172
|
* using the key itself. If the key is not found, `undefined` is
|
|
162
173
|
*/
|
|
163
|
-
get(key: K
|
|
164
|
-
if (
|
|
165
|
-
const
|
|
166
|
-
|
|
174
|
+
get(key: K): V | undefined {
|
|
175
|
+
if (isWeakKey(key)) {
|
|
176
|
+
const hash = this._objHashFn(key);
|
|
177
|
+
const node = this._objMap.get(hash);
|
|
178
|
+
return node ? node.value : undefined;
|
|
179
|
+
} else {
|
|
180
|
+
const hash = this._hashFn(key);
|
|
181
|
+
const node = this._noObjMap[hash];
|
|
182
|
+
return node ? node.value : undefined;
|
|
167
183
|
}
|
|
168
|
-
const node = this._orgMap[<string>(<unknown>key)];
|
|
169
|
-
return node ? node.value : undefined;
|
|
170
184
|
}
|
|
171
185
|
|
|
172
186
|
/**
|
|
@@ -196,25 +210,37 @@ export class HashMap<K = any, V = any> {
|
|
|
196
210
|
* The `delete` function removes a key-value pair from a map-like data structure.
|
|
197
211
|
* @param {K} key - The `key` parameter is the key that you want to delete from the data structure.
|
|
198
212
|
* It can be of any type, but typically it is a string or an object.
|
|
199
|
-
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
|
|
200
|
-
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that the
|
|
201
|
-
* `key` parameter is an object key. If `isObjectKey` is `false`, it means that the
|
|
202
213
|
* @returns a boolean value. It returns `true` if the deletion was successful, and `false` if the key
|
|
203
214
|
* was not found.
|
|
204
215
|
*/
|
|
205
|
-
delete(key: K
|
|
216
|
+
delete(key: K) {
|
|
206
217
|
let node;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
node = this.
|
|
212
|
-
|
|
218
|
+
|
|
219
|
+
if (isWeakKey(key)) {
|
|
220
|
+
const hash = this._objHashFn(key);
|
|
221
|
+
// Get nodes from WeakMap
|
|
222
|
+
node = this._objMap.get(hash);
|
|
223
|
+
|
|
224
|
+
if (!node) {
|
|
225
|
+
return false; // If the node does not exist, return false
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Remove nodes from WeakMap
|
|
229
|
+
this._objMap.delete(hash);
|
|
213
230
|
} else {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
231
|
+
const hash = this._hashFn(key);
|
|
232
|
+
// Get nodes from noObjMap
|
|
233
|
+
node = this._noObjMap[hash];
|
|
234
|
+
|
|
235
|
+
if (!node) {
|
|
236
|
+
return false; // If the node does not exist, return false
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Remove nodes from orgMap
|
|
240
|
+
delete this._noObjMap[hash];
|
|
217
241
|
}
|
|
242
|
+
|
|
243
|
+
// Remove node from doubly linked list
|
|
218
244
|
this._deleteNode(node);
|
|
219
245
|
return true;
|
|
220
246
|
}
|
|
@@ -257,13 +283,7 @@ export class HashMap<K = any, V = any> {
|
|
|
257
283
|
* The `clear` function clears all the elements in a data structure and resets its properties.
|
|
258
284
|
*/
|
|
259
285
|
clear() {
|
|
260
|
-
|
|
261
|
-
// this._nodes.forEach(el => {
|
|
262
|
-
// delete (<Record<symbol, number>><unknown>el.key)[OBJ_KEY_INDEX];
|
|
263
|
-
// });
|
|
264
|
-
this._nodes = [];
|
|
265
|
-
this._orgMap = {};
|
|
266
|
-
Object.setPrototypeOf(this._orgMap, null);
|
|
286
|
+
this._noObjMap = {};
|
|
267
287
|
this._size = 0;
|
|
268
288
|
this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;
|
|
269
289
|
}
|
|
@@ -286,6 +306,33 @@ export class HashMap<K = any, V = any> {
|
|
|
286
306
|
}
|
|
287
307
|
}
|
|
288
308
|
|
|
309
|
+
filter(predicate: (element: [K, V], map: HashMap<K, V>) => boolean): HashMap<K, V> {
|
|
310
|
+
const filteredMap = new HashMap<K, V>();
|
|
311
|
+
for (const [key, value] of this) {
|
|
312
|
+
if (predicate([key, value], this)) {
|
|
313
|
+
filteredMap.set(key, value);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return filteredMap;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
map<NV>(callback: (element: [K, V], map: HashMap<K, V>) => NV): HashMap<K, NV> {
|
|
320
|
+
const mappedMap = new HashMap<K, NV>();
|
|
321
|
+
for (const [key, value] of this) {
|
|
322
|
+
const newValue = callback([key, value], this);
|
|
323
|
+
mappedMap.set(key, newValue);
|
|
324
|
+
}
|
|
325
|
+
return mappedMap;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
reduce<A>(callback: (accumulator: A, element: [K, V], map: HashMap<K, V>) => A, initialValue: A): A {
|
|
329
|
+
let accumulator = initialValue;
|
|
330
|
+
for (const element of this) {
|
|
331
|
+
accumulator = callback(accumulator, element, this);
|
|
332
|
+
}
|
|
333
|
+
return accumulator;
|
|
334
|
+
}
|
|
335
|
+
|
|
289
336
|
/**
|
|
290
337
|
* Time Complexity: O(n), where n is the number of elements in the HashMap.
|
|
291
338
|
* Space Complexity: O(1)
|
|
@@ -310,16 +357,19 @@ export class HashMap<K = any, V = any> {
|
|
|
310
357
|
* represents a node in a linked list. It contains a key-value pair and references to the previous
|
|
311
358
|
* and next nodes in the list.
|
|
312
359
|
*/
|
|
313
|
-
protected _deleteNode(node: HashMapLinkedNode<K, V>) {
|
|
360
|
+
protected _deleteNode(node: HashMapLinkedNode<K, V | undefined>) {
|
|
314
361
|
const { prev, next } = node;
|
|
315
362
|
prev.next = next;
|
|
316
363
|
next.prev = prev;
|
|
364
|
+
|
|
317
365
|
if (node === this._head) {
|
|
318
366
|
this._head = next;
|
|
319
367
|
}
|
|
368
|
+
|
|
320
369
|
if (node === this._tail) {
|
|
321
370
|
this._tail = prev;
|
|
322
371
|
}
|
|
372
|
+
|
|
323
373
|
this._size -= 1;
|
|
324
374
|
}
|
|
325
375
|
}
|
package/src/utils/utils.ts
CHANGED
|
@@ -93,7 +93,7 @@ export const throwRangeError = (message = 'The value is off-limits.'): void => {
|
|
|
93
93
|
throw new RangeError(message);
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
-
export const
|
|
96
|
+
export const isWeakKey = (input: unknown): input is WeakKey => {
|
|
97
97
|
const inputType = typeof input;
|
|
98
98
|
return (inputType === 'object' && input !== null) || inputType === 'function';
|
|
99
99
|
};
|
|
@@ -14,6 +14,7 @@ suite.add(`${MILLION.toLocaleString()} set`, () => {
|
|
|
14
14
|
hm.set(i, i);
|
|
15
15
|
}
|
|
16
16
|
});
|
|
17
|
+
|
|
17
18
|
if (isCompetitor) {
|
|
18
19
|
suite.add(`${MILLION.toLocaleString()} CPT set`, () => {
|
|
19
20
|
const hm = new CHashMap<number, number>();
|
|
@@ -23,6 +24,19 @@ if (isCompetitor) {
|
|
|
23
24
|
}
|
|
24
25
|
});
|
|
25
26
|
}
|
|
27
|
+
|
|
28
|
+
suite.add(`${MILLION.toLocaleString()} Map set`, () => {
|
|
29
|
+
const hm = new Map<number, number>();
|
|
30
|
+
|
|
31
|
+
for (let i = 0; i < MILLION; i++) hm.set(i, i);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
suite.add(`${MILLION.toLocaleString()} Set add`, () => {
|
|
35
|
+
const hs = new Set<number>();
|
|
36
|
+
|
|
37
|
+
for (let i = 0; i < MILLION; i++) hs.add(i);
|
|
38
|
+
});
|
|
39
|
+
|
|
26
40
|
suite.add(`${MILLION.toLocaleString()} set & get`, () => {
|
|
27
41
|
const hm = new HashMap<number, number>();
|
|
28
42
|
|
|
@@ -33,6 +47,7 @@ suite.add(`${MILLION.toLocaleString()} set & get`, () => {
|
|
|
33
47
|
hm.get(i);
|
|
34
48
|
}
|
|
35
49
|
});
|
|
50
|
+
|
|
36
51
|
if (isCompetitor) {
|
|
37
52
|
suite.add(`${MILLION.toLocaleString()} CPT set & get`, () => {
|
|
38
53
|
const hm = new CHashMap<number, number>();
|
|
@@ -45,4 +60,64 @@ if (isCompetitor) {
|
|
|
45
60
|
}
|
|
46
61
|
});
|
|
47
62
|
}
|
|
63
|
+
|
|
64
|
+
suite.add(`${MILLION.toLocaleString()} Map set & get`, () => {
|
|
65
|
+
const hm = new Map<number, number>();
|
|
66
|
+
|
|
67
|
+
for (let i = 0; i < MILLION; i++) {
|
|
68
|
+
hm.set(i, i);
|
|
69
|
+
}
|
|
70
|
+
for (let i = 0; i < MILLION; i++) {
|
|
71
|
+
hm.get(i);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
suite.add(`${MILLION.toLocaleString()} Set add & has`, () => {
|
|
76
|
+
const hs = new Set<number>();
|
|
77
|
+
|
|
78
|
+
for (let i = 0; i < MILLION; i++) hs.add(i);
|
|
79
|
+
|
|
80
|
+
for (let i = 0; i < MILLION; i++) hs.has(i);
|
|
81
|
+
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
suite.add(`${MILLION.toLocaleString()} ObjKey set & get`, () => {
|
|
85
|
+
const hm = new HashMap<[number, number], number>();
|
|
86
|
+
const objKeys:[number, number][] = [];
|
|
87
|
+
for (let i = 0; i < MILLION; i++) {
|
|
88
|
+
const obj: [number, number] = [i, i];
|
|
89
|
+
objKeys.push(obj)
|
|
90
|
+
hm.set(obj, i);
|
|
91
|
+
}
|
|
92
|
+
for (let i = 0; i < MILLION; i++) {
|
|
93
|
+
hm.get(objKeys[i]);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
suite.add(`${MILLION.toLocaleString()} Map ObjKey set & get`, () => {
|
|
98
|
+
const hm = new Map<[number, number], number>();
|
|
99
|
+
const objs:[number, number][] = [];
|
|
100
|
+
for (let i = 0; i < MILLION; i++) {
|
|
101
|
+
const obj: [number, number] = [i, i];
|
|
102
|
+
objs.push(obj)
|
|
103
|
+
hm.set(obj, i);
|
|
104
|
+
}
|
|
105
|
+
for (let i = 0; i < MILLION; i++) {
|
|
106
|
+
hm.get(objs[i]);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
suite.add(`${MILLION.toLocaleString()} Set ObjKey add & has`, () => {
|
|
111
|
+
const hs = new Set<[number, number]>();
|
|
112
|
+
const objs:[number, number][] = [];
|
|
113
|
+
for (let i = 0; i < MILLION; i++) {
|
|
114
|
+
const obj: [number, number] = [i, i];
|
|
115
|
+
objs.push(obj)
|
|
116
|
+
hs.add(obj);
|
|
117
|
+
}
|
|
118
|
+
for (let i = 0; i < MILLION; i++) {
|
|
119
|
+
hs.has(objs[i]);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
48
123
|
export { suite };
|
|
@@ -229,3 +229,35 @@ describe('HashMap', () => {
|
|
|
229
229
|
expect(hashMap.getAt(1)).toEqual(['key2', 'value2']);
|
|
230
230
|
});
|
|
231
231
|
});
|
|
232
|
+
|
|
233
|
+
describe('HashMap for coordinate object keys', () => {
|
|
234
|
+
const hashMap: HashMap<[number, number], number> = new HashMap();
|
|
235
|
+
const codObjs: [number, number][] = [];
|
|
236
|
+
|
|
237
|
+
test('set elements in hash map', () => {
|
|
238
|
+
for (let i = 0; i < 1000; i++) {
|
|
239
|
+
const codObj: [number, number] = [getRandomInt(-10000, 10000), i];
|
|
240
|
+
codObjs.push(codObj);
|
|
241
|
+
hashMap.set(codObj, i);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
test('get elements in hash map', () => {
|
|
246
|
+
for (let i = 0; i < 1000; i++) {
|
|
247
|
+
const codObj = codObjs[i];
|
|
248
|
+
if (codObj) {
|
|
249
|
+
expect(hashMap.get(codObj)).toBe(i);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test('delete elements in hash map', () => {
|
|
255
|
+
for (let i = 0; i < 1000; i++) {
|
|
256
|
+
if (i === 500) expect(hashMap.size).toBe(500)
|
|
257
|
+
const codObj = codObjs[i];
|
|
258
|
+
if (codObj) hashMap.delete(codObj);
|
|
259
|
+
}
|
|
260
|
+
expect(hashMap.size).toBe(0);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
});
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* data-structure-typed
|
|
3
|
-
*
|
|
4
|
-
* @author Tyler Zeng
|
|
5
|
-
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
|
-
* @license MIT License
|
|
7
|
-
*/
|
|
8
|
-
export declare class CoordinateMap<V> extends Map<any, V> {
|
|
9
|
-
constructor(joint?: string);
|
|
10
|
-
protected _joint: string;
|
|
11
|
-
get joint(): string;
|
|
12
|
-
/**
|
|
13
|
-
* The "has" function overrides the base class's "has" function and checks if a key exists in the map by joining the
|
|
14
|
-
* key array with a specified delimiter.
|
|
15
|
-
* @param {number[]} key - The parameter "key" is an array of numbers.
|
|
16
|
-
* @returns The `has` method is being overridden to return the result of calling the `has` method of the superclass
|
|
17
|
-
* (`super.has`) with the `key` array joined together using the `_joint` property.
|
|
18
|
-
*/
|
|
19
|
-
has(key: number[]): boolean;
|
|
20
|
-
/**
|
|
21
|
-
* The function overrides the set method of a Map object to convert the key from an array to a string using a specified
|
|
22
|
-
* delimiter before calling the original set method.
|
|
23
|
-
* @param {number[]} key - The key parameter is an array of numbers.
|
|
24
|
-
* @param {V} value - The value parameter is the value that you want to associate with the specified key.
|
|
25
|
-
* @returns The `set` method is returning the result of calling the `set` method of the superclass
|
|
26
|
-
* (`super.set(key.join(this._joint), value)`).
|
|
27
|
-
*/
|
|
28
|
-
set(key: number[], value: V): this;
|
|
29
|
-
/**
|
|
30
|
-
* The function overrides the get method to join the key array with a specified joint and then calls the super get
|
|
31
|
-
* method.
|
|
32
|
-
* @param {number[]} key - An array of numbers
|
|
33
|
-
* @returns The code is returning the value associated with the specified key in the map.
|
|
34
|
-
*/
|
|
35
|
-
get(key: number[]): V | undefined;
|
|
36
|
-
/**
|
|
37
|
-
* The function overrides the delete method and joins the key array using a specified joint character before calling
|
|
38
|
-
* the super delete method.
|
|
39
|
-
* @param {number[]} key - An array of numbers that represents the key to be deleted.
|
|
40
|
-
* @returns The `delete` method is returning the result of calling the `delete` method on the superclass, with the
|
|
41
|
-
* `key` array joined together using the `_joint` property.
|
|
42
|
-
*/
|
|
43
|
-
delete(key: number[]): boolean;
|
|
44
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CoordinateMap = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* data-structure-typed
|
|
6
|
-
*
|
|
7
|
-
* @author Tyler Zeng
|
|
8
|
-
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
9
|
-
* @license MIT License
|
|
10
|
-
*/
|
|
11
|
-
class CoordinateMap extends Map {
|
|
12
|
-
constructor(joint) {
|
|
13
|
-
super();
|
|
14
|
-
this._joint = '_';
|
|
15
|
-
if (joint !== undefined)
|
|
16
|
-
this._joint = joint;
|
|
17
|
-
}
|
|
18
|
-
get joint() {
|
|
19
|
-
return this._joint;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* The "has" function overrides the base class's "has" function and checks if a key exists in the map by joining the
|
|
23
|
-
* key array with a specified delimiter.
|
|
24
|
-
* @param {number[]} key - The parameter "key" is an array of numbers.
|
|
25
|
-
* @returns The `has` method is being overridden to return the result of calling the `has` method of the superclass
|
|
26
|
-
* (`super.has`) with the `key` array joined together using the `_joint` property.
|
|
27
|
-
*/
|
|
28
|
-
has(key) {
|
|
29
|
-
return super.has(key.join(this._joint));
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* The function overrides the set method of a Map object to convert the key from an array to a string using a specified
|
|
33
|
-
* delimiter before calling the original set method.
|
|
34
|
-
* @param {number[]} key - The key parameter is an array of numbers.
|
|
35
|
-
* @param {V} value - The value parameter is the value that you want to associate with the specified key.
|
|
36
|
-
* @returns The `set` method is returning the result of calling the `set` method of the superclass
|
|
37
|
-
* (`super.set(key.join(this._joint), value)`).
|
|
38
|
-
*/
|
|
39
|
-
set(key, value) {
|
|
40
|
-
return super.set(key.join(this._joint), value);
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* The function overrides the get method to join the key array with a specified joint and then calls the super get
|
|
44
|
-
* method.
|
|
45
|
-
* @param {number[]} key - An array of numbers
|
|
46
|
-
* @returns The code is returning the value associated with the specified key in the map.
|
|
47
|
-
*/
|
|
48
|
-
get(key) {
|
|
49
|
-
return super.get(key.join(this._joint));
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* The function overrides the delete method and joins the key array using a specified joint character before calling
|
|
53
|
-
* the super delete method.
|
|
54
|
-
* @param {number[]} key - An array of numbers that represents the key to be deleted.
|
|
55
|
-
* @returns The `delete` method is returning the result of calling the `delete` method on the superclass, with the
|
|
56
|
-
* `key` array joined together using the `_joint` property.
|
|
57
|
-
*/
|
|
58
|
-
delete(key) {
|
|
59
|
-
return super.delete(key.join(this._joint));
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
exports.CoordinateMap = CoordinateMap;
|
|
63
|
-
//# sourceMappingURL=coordinate-map.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"coordinate-map.js","sourceRoot":"","sources":["../../../../src/data-structures/hash/coordinate-map.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACH,MAAa,aAAiB,SAAQ,GAAW;IAC/C,YAAY,KAAc;QACxB,KAAK,EAAE,CAAC;QAIA,WAAM,GAAG,GAAG,CAAC;QAHrB,IAAI,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IAC/C,CAAC;IAID,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;;;;OAMG;IACM,GAAG,CAAC,GAAa;QACxB,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;;OAOG;IACM,GAAG,CAAC,GAAa,EAAE,KAAQ;QAClC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IAED;;;;;OAKG;IACM,GAAG,CAAC,GAAa;QACxB,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;OAMG;IACM,MAAM,CAAC,GAAa;QAC3B,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C,CAAC;CACF;AAvDD,sCAuDC"}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* data-structure-typed
|
|
3
|
-
*
|
|
4
|
-
* @author Tyler Zeng
|
|
5
|
-
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
|
-
* @license MIT License
|
|
7
|
-
*/
|
|
8
|
-
export declare class CoordinateSet extends Set<any> {
|
|
9
|
-
constructor(joint?: string);
|
|
10
|
-
protected _joint: string;
|
|
11
|
-
get joint(): string;
|
|
12
|
-
/**
|
|
13
|
-
* The "has" function overrides the "has" method of the superclass and checks if a value exists in an array after
|
|
14
|
-
* joining its elements with a specified separator.
|
|
15
|
-
* @param {number[]} value - The parameter "value" is an array of numbers.
|
|
16
|
-
* @returns The overridden `has` method is returning the result of calling the `has` method of the superclass, passing
|
|
17
|
-
* in the joined value as an argument.
|
|
18
|
-
*/
|
|
19
|
-
has(value: number[]): boolean;
|
|
20
|
-
/**
|
|
21
|
-
* The "add" function overrides the parent class's "add" function by joining the elements of the input array with a
|
|
22
|
-
* specified delimiter before calling the parent class's "add" function.
|
|
23
|
-
* @param {number[]} value - An array of numbers
|
|
24
|
-
* @returns The overridden `add` method is returning the result of calling the `add` method of the superclass
|
|
25
|
-
* (`super.add`) with the joined string representation of the `value` array (`value.join(this._joint)`).
|
|
26
|
-
*/
|
|
27
|
-
add(value: number[]): this;
|
|
28
|
-
/**
|
|
29
|
-
* The function overrides the delete method and deletes an element from a Set by joining the elements of the input
|
|
30
|
-
* array with a specified joint and then calling the delete method of the parent class.
|
|
31
|
-
* @param {number[]} value - An array of numbers
|
|
32
|
-
* @returns The `delete` method is returning the result of calling the `delete` method of the superclass, with the
|
|
33
|
-
* `value` array joined together using the `_joint` property.
|
|
34
|
-
*/
|
|
35
|
-
delete(value: number[]): boolean;
|
|
36
|
-
}
|