data-structure-typed 2.5.3 → 2.6.1
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/.github/workflows/ci.yml +7 -2
- package/.github/workflows/release-package.yml +9 -2
- package/.husky/pre-commit +3 -0
- package/CHANGELOG.md +1 -1
- package/MIGRATION.md +48 -0
- package/README.md +20 -2
- package/README_CN.md +20 -2
- package/SPECIFICATION.md +24 -0
- package/SPECIFICATION.zh-CN.md +24 -0
- package/dist/cjs/binary-tree.cjs +1897 -19
- package/dist/cjs/graph.cjs +174 -0
- package/dist/cjs/hash.cjs +33 -0
- package/dist/cjs/heap.cjs +71 -0
- package/dist/cjs/index.cjs +2383 -3
- package/dist/cjs/linked-list.cjs +224 -2
- package/dist/cjs/matrix.cjs +24 -0
- package/dist/cjs/priority-queue.cjs +71 -0
- package/dist/cjs/queue.cjs +221 -1
- package/dist/cjs/stack.cjs +59 -0
- package/dist/cjs/trie.cjs +62 -0
- package/dist/cjs-legacy/binary-tree.cjs +1897 -19
- package/dist/cjs-legacy/graph.cjs +174 -0
- package/dist/cjs-legacy/hash.cjs +33 -0
- package/dist/cjs-legacy/heap.cjs +71 -0
- package/dist/cjs-legacy/index.cjs +2383 -3
- package/dist/cjs-legacy/linked-list.cjs +224 -2
- package/dist/cjs-legacy/matrix.cjs +24 -0
- package/dist/cjs-legacy/priority-queue.cjs +71 -0
- package/dist/cjs-legacy/queue.cjs +221 -1
- package/dist/cjs-legacy/stack.cjs +59 -0
- package/dist/cjs-legacy/trie.cjs +62 -0
- package/dist/esm/binary-tree.mjs +1897 -19
- package/dist/esm/graph.mjs +174 -0
- package/dist/esm/hash.mjs +33 -0
- package/dist/esm/heap.mjs +71 -0
- package/dist/esm/index.mjs +2383 -3
- package/dist/esm/linked-list.mjs +224 -2
- package/dist/esm/matrix.mjs +24 -0
- package/dist/esm/priority-queue.mjs +71 -0
- package/dist/esm/queue.mjs +221 -1
- package/dist/esm/stack.mjs +59 -0
- package/dist/esm/trie.mjs +62 -0
- package/dist/esm-legacy/binary-tree.mjs +1897 -19
- package/dist/esm-legacy/graph.mjs +174 -0
- package/dist/esm-legacy/hash.mjs +33 -0
- package/dist/esm-legacy/heap.mjs +71 -0
- package/dist/esm-legacy/index.mjs +2383 -3
- package/dist/esm-legacy/linked-list.mjs +224 -2
- package/dist/esm-legacy/matrix.mjs +24 -0
- package/dist/esm-legacy/priority-queue.mjs +71 -0
- package/dist/esm-legacy/queue.mjs +221 -1
- package/dist/esm-legacy/stack.mjs +59 -0
- package/dist/esm-legacy/trie.mjs +62 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +17 -0
- package/dist/types/data-structures/base/linear-base.d.ts +6 -0
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +36 -0
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +42 -0
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +75 -0
- package/dist/types/data-structures/binary-tree/bst.d.ts +72 -0
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +57 -0
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +18 -0
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +375 -0
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +389 -0
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +330 -0
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +438 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +30 -0
- package/dist/types/data-structures/graph/undirected-graph.d.ts +27 -0
- package/dist/types/data-structures/hash/hash-map.d.ts +33 -0
- package/dist/types/data-structures/heap/heap.d.ts +42 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +75 -2
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +45 -0
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +54 -0
- package/dist/types/data-structures/matrix/matrix.d.ts +24 -0
- package/dist/types/data-structures/queue/deque.d.ts +90 -1
- package/dist/types/data-structures/queue/queue.d.ts +36 -0
- package/dist/types/data-structures/stack/stack.d.ts +30 -0
- package/dist/types/data-structures/trie/trie.d.ts +36 -0
- package/dist/umd/data-structure-typed.js +2383 -3
- package/dist/umd/data-structure-typed.min.js +3 -3
- package/docs-site-docusaurus/docs/api/classes/AVLTree.md +108 -108
- package/docs-site-docusaurus/docs/api/classes/BST.md +101 -101
- package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +13 -13
- package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +66 -66
- package/docs-site-docusaurus/docs/api/classes/Deque.md +235 -51
- package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +21 -21
- package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +231 -67
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +9 -9
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +1 -1
- package/docs-site-docusaurus/docs/api/classes/HashMap.md +14 -14
- package/docs-site-docusaurus/docs/api/classes/Heap.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +83 -13
- package/docs-site-docusaurus/docs/api/classes/LinearBase.md +124 -20
- package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +140 -32
- package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +30 -26
- package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +159 -51
- package/docs-site-docusaurus/docs/api/classes/MapGraph.md +20 -20
- package/docs-site-docusaurus/docs/api/classes/Matrix.md +23 -23
- package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/MinHeap.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/Queue.md +142 -34
- package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +117 -117
- package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +8 -8
- package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +158 -50
- package/docs-site-docusaurus/docs/api/classes/SkipList.md +21 -21
- package/docs-site-docusaurus/docs/api/classes/Stack.md +108 -26
- package/docs-site-docusaurus/docs/api/classes/TreeMap.md +33 -33
- package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +75 -39
- package/docs-site-docusaurus/docs/api/classes/TreeSet.md +301 -39
- package/docs-site-docusaurus/docs/api/classes/Trie.md +110 -28
- package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +20 -20
- package/jest.integration.config.js +1 -2
- package/package.json +51 -50
- package/src/common/error.ts +15 -32
- package/src/common/index.ts +0 -3
- package/src/data-structures/base/iterable-element-base.ts +32 -3
- package/src/data-structures/base/linear-base.ts +13 -36
- package/src/data-structures/binary-tree/avl-tree.ts +31 -493
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +47 -530
- package/src/data-structures/binary-tree/binary-tree.ts +326 -1236
- package/src/data-structures/binary-tree/bst.ts +158 -1010
- package/src/data-structures/binary-tree/red-black-tree.ts +451 -1233
- package/src/data-structures/binary-tree/segment-tree.ts +73 -333
- package/src/data-structures/binary-tree/tree-map.ts +462 -4749
- package/src/data-structures/binary-tree/tree-multi-map.ts +310 -4530
- package/src/data-structures/binary-tree/tree-multi-set.ts +300 -3652
- package/src/data-structures/binary-tree/tree-set.ts +437 -4443
- package/src/data-structures/graph/abstract-graph.ts +98 -167
- package/src/data-structures/graph/directed-graph.ts +137 -532
- package/src/data-structures/graph/map-graph.ts +0 -3
- package/src/data-structures/graph/undirected-graph.ts +132 -484
- package/src/data-structures/hash/hash-map.ts +154 -549
- package/src/data-structures/heap/heap.ts +200 -753
- package/src/data-structures/linked-list/doubly-linked-list.ts +153 -809
- package/src/data-structures/linked-list/singly-linked-list.ts +122 -749
- package/src/data-structures/linked-list/skip-linked-list.ts +211 -864
- package/src/data-structures/matrix/matrix.ts +179 -494
- package/src/data-structures/matrix/navigator.ts +0 -1
- package/src/data-structures/priority-queue/max-priority-queue.ts +1 -6
- package/src/data-structures/priority-queue/min-priority-queue.ts +6 -11
- package/src/data-structures/priority-queue/priority-queue.ts +1 -2
- package/src/data-structures/queue/deque.ts +241 -807
- package/src/data-structures/queue/queue.ts +102 -589
- package/src/data-structures/stack/stack.ts +76 -475
- package/src/data-structures/trie/trie.ts +98 -592
- package/src/types/common.ts +0 -10
- package/src/types/data-structures/binary-tree/bst.ts +0 -7
- package/src/types/data-structures/binary-tree/red-black-tree.ts +0 -1
- package/src/types/data-structures/graph/abstract-graph.ts +0 -2
- package/src/types/data-structures/hash/hash-map.ts +0 -3
- package/src/types/data-structures/hash/index.ts +0 -1
- package/src/types/data-structures/matrix/navigator.ts +0 -2
- package/src/types/utils/utils.ts +0 -7
- package/src/types/utils/validate-type.ts +0 -7
- package/src/utils/number.ts +0 -2
- package/src/utils/utils.ts +0 -5
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
8
|
import type {
|
|
10
9
|
EntryCallback,
|
|
11
10
|
HashMapLinkedNode,
|
|
@@ -82,19 +81,28 @@ import { ERR, raise } from '../../common';
|
|
|
82
81
|
* console.log(activeCount); // 2;
|
|
83
82
|
* @example
|
|
84
83
|
* // Aggregate values
|
|
85
|
-
* const counts = new HashMap<string, number>([
|
|
84
|
+
* const counts = new HashMap<string, number>([
|
|
85
|
+
* ['a', 5],
|
|
86
|
+
* ['b', 3],
|
|
87
|
+
* ['c', 8]
|
|
88
|
+
* ]);
|
|
86
89
|
*
|
|
87
90
|
* const total = counts.reduce((sum, v) => sum + (v ?? 0), 0);
|
|
88
91
|
* console.log(total); // 16;
|
|
89
92
|
* @example
|
|
90
93
|
* // Iterate over entries
|
|
91
|
-
* const map = new HashMap<string, number>([
|
|
94
|
+
* const map = new HashMap<string, number>([
|
|
95
|
+
* ['x', 1],
|
|
96
|
+
* ['y', 2]
|
|
97
|
+
* ]);
|
|
92
98
|
* const keys: string[] = [];
|
|
93
99
|
*
|
|
94
100
|
* map.forEach((v, k) => keys.push(k));
|
|
95
101
|
* console.log(keys.sort()); // ['x', 'y'];
|
|
96
102
|
*/
|
|
97
103
|
export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {
|
|
104
|
+
protected readonly _toEntryFn?: (rawElement: R) => [K, V];
|
|
105
|
+
|
|
98
106
|
/**
|
|
99
107
|
* Create a HashMap and optionally bulk-insert entries.
|
|
100
108
|
* @remarks Time O(N), Space O(N)
|
|
@@ -134,8 +142,6 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
134
142
|
return this._objMap;
|
|
135
143
|
}
|
|
136
144
|
|
|
137
|
-
protected readonly _toEntryFn?: (rawElement: R) => [K, V];
|
|
138
|
-
|
|
139
145
|
/**
|
|
140
146
|
* Get the raw→entry converter function if present.
|
|
141
147
|
* @remarks Time O(1), Space O(1)
|
|
@@ -171,47 +177,10 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
171
177
|
* Check whether the map is empty.
|
|
172
178
|
* @remarks Time O(1), Space O(1)
|
|
173
179
|
* @returns True if size is 0.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
* @example
|
|
212
|
-
* // Check if empty
|
|
213
|
-
* const map = new HashMap();
|
|
214
|
-
* console.log(map.isEmpty()); // true;
|
|
180
|
+
* @example
|
|
181
|
+
* // Check if empty
|
|
182
|
+
* const map = new HashMap();
|
|
183
|
+
* console.log(map.isEmpty()); // true;
|
|
215
184
|
*/
|
|
216
185
|
isEmpty(): boolean {
|
|
217
186
|
return this._size === 0;
|
|
@@ -221,48 +190,14 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
221
190
|
* Remove all entries and reset counters.
|
|
222
191
|
* @remarks Time O(N), Space O(1)
|
|
223
192
|
* @returns void
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
* @example
|
|
262
|
-
* // Remove all entries
|
|
263
|
-
* const map = new HashMap<string, number>([['a', 1], ['b', 2]]);
|
|
264
|
-
* map.clear();
|
|
265
|
-
* console.log(map.isEmpty()); // true;
|
|
193
|
+
* @example
|
|
194
|
+
* // Remove all entries
|
|
195
|
+
* const map = new HashMap<string, number>([
|
|
196
|
+
* ['a', 1],
|
|
197
|
+
* ['b', 2]
|
|
198
|
+
* ]);
|
|
199
|
+
* map.clear();
|
|
200
|
+
* console.log(map.isEmpty()); // true;
|
|
266
201
|
*/
|
|
267
202
|
clear(): void {
|
|
268
203
|
this._store = {};
|
|
@@ -285,102 +220,24 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
285
220
|
* @param key - Key.
|
|
286
221
|
* @param value - Value.
|
|
287
222
|
* @returns True when the operation succeeds.
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
* @example
|
|
367
|
-
* // basic HashMap creation and set operation
|
|
368
|
-
* // Create a simple HashMap with key-value pairs
|
|
369
|
-
* const map = new HashMap<number, string>([
|
|
370
|
-
* [1, 'one'],
|
|
371
|
-
* [2, 'two'],
|
|
372
|
-
* [3, 'three']
|
|
373
|
-
* ]);
|
|
374
|
-
*
|
|
375
|
-
* // Verify size
|
|
376
|
-
* console.log(map.size); // 3;
|
|
377
|
-
*
|
|
378
|
-
* // Set a new key-value pair
|
|
379
|
-
* map.set(4, 'four');
|
|
380
|
-
* console.log(map.size); // 4;
|
|
381
|
-
*
|
|
382
|
-
* // Verify entries
|
|
383
|
-
* console.log([...map.entries()]); // length: 4;
|
|
223
|
+
* @example
|
|
224
|
+
* // basic HashMap creation and set operation
|
|
225
|
+
* // Create a simple HashMap with key-value pairs
|
|
226
|
+
* const map = new HashMap<number, string>([
|
|
227
|
+
* [1, 'one'],
|
|
228
|
+
* [2, 'two'],
|
|
229
|
+
* [3, 'three']
|
|
230
|
+
* ]);
|
|
231
|
+
*
|
|
232
|
+
* // Verify size
|
|
233
|
+
* console.log(map.size); // 3;
|
|
234
|
+
*
|
|
235
|
+
* // Set a new key-value pair
|
|
236
|
+
* map.set(4, 'four');
|
|
237
|
+
* console.log(map.size); // 4;
|
|
238
|
+
*
|
|
239
|
+
* // Verify entries
|
|
240
|
+
* console.log([...map.entries()]); // length: 4;
|
|
384
241
|
*/
|
|
385
242
|
set(key: K, value: V): this {
|
|
386
243
|
if (this._isObjKey(key)) {
|
|
@@ -399,48 +256,15 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
399
256
|
* @remarks Time O(N), Space O(N)
|
|
400
257
|
* @param entryOrRawElements - Iterable of entries or raw elements to insert.
|
|
401
258
|
* @returns Array of per-entry results.
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
* @example
|
|
440
|
-
* // Add multiple entries
|
|
441
|
-
* const map = new HashMap<string, number>();
|
|
442
|
-
* map.setMany([['a', 1], ['b', 2], ['c', 3]]);
|
|
443
|
-
* console.log(map.size); // 3;
|
|
259
|
+
* @example
|
|
260
|
+
* // Add multiple entries
|
|
261
|
+
* const map = new HashMap<string, number>();
|
|
262
|
+
* map.setMany([
|
|
263
|
+
* ['a', 1],
|
|
264
|
+
* ['b', 2],
|
|
265
|
+
* ['c', 3]
|
|
266
|
+
* ]);
|
|
267
|
+
* console.log(map.size); // 3;
|
|
444
268
|
*/
|
|
445
269
|
setMany(entryOrRawElements: Iterable<R | [K, V]>): boolean[] {
|
|
446
270
|
const results: boolean[] = [];
|
|
@@ -462,66 +286,27 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
462
286
|
* @remarks Time O(1), Space O(1)
|
|
463
287
|
* @param key - Key to look up.
|
|
464
288
|
* @returns Value or undefined.
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
* @example
|
|
505
|
-
* // HashMap get and has operations
|
|
506
|
-
* const map = new HashMap<string, number>([
|
|
507
|
-
* ['apple', 1],
|
|
508
|
-
* ['banana', 2],
|
|
509
|
-
* ['cherry', 3]
|
|
510
|
-
* ]);
|
|
511
|
-
*
|
|
512
|
-
* // Check if key exists
|
|
513
|
-
* console.log(map.has('apple')); // true;
|
|
514
|
-
* console.log(map.has('date')); // false;
|
|
515
|
-
*
|
|
516
|
-
* // Get value by key
|
|
517
|
-
* console.log(map.get('banana')); // 2;
|
|
518
|
-
* console.log(map.get('grape')); // undefined;
|
|
519
|
-
*
|
|
520
|
-
* // Get all keys and values
|
|
521
|
-
* const keys = [...map.keys()];
|
|
522
|
-
* const values = [...map.values()];
|
|
523
|
-
* console.log(keys); // contains 'apple';
|
|
524
|
-
* console.log(values); // contains 3;
|
|
289
|
+
* @example
|
|
290
|
+
* // HashMap get and has operations
|
|
291
|
+
* const map = new HashMap<string, number>([
|
|
292
|
+
* ['apple', 1],
|
|
293
|
+
* ['banana', 2],
|
|
294
|
+
* ['cherry', 3]
|
|
295
|
+
* ]);
|
|
296
|
+
*
|
|
297
|
+
* // Check if key exists
|
|
298
|
+
* console.log(map.has('apple')); // true;
|
|
299
|
+
* console.log(map.has('date')); // false;
|
|
300
|
+
*
|
|
301
|
+
* // Get value by key
|
|
302
|
+
* console.log(map.get('banana')); // 2;
|
|
303
|
+
* console.log(map.get('grape')); // undefined;
|
|
304
|
+
*
|
|
305
|
+
* // Get all keys and values
|
|
306
|
+
* const keys = [...map.keys()];
|
|
307
|
+
* const values = [...map.values()];
|
|
308
|
+
* console.log(keys); // contains 'apple';
|
|
309
|
+
* console.log(values); // contains 3;
|
|
525
310
|
*/
|
|
526
311
|
override get(key: K): V | undefined {
|
|
527
312
|
if (this._isObjKey(key)) return this.objMap.get(key);
|
|
@@ -534,51 +319,15 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
534
319
|
* @remarks Time O(1), Space O(1)
|
|
535
320
|
* @param key - Key to test.
|
|
536
321
|
* @returns True if present.
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
* @example
|
|
577
|
-
* // Check key existence
|
|
578
|
-
* const map = new HashMap<string, number>([['a', 1], ['b', 2]]);
|
|
579
|
-
*
|
|
580
|
-
* console.log(map.has('a')); // true;
|
|
581
|
-
* console.log(map.has('z')); // false;
|
|
322
|
+
* @example
|
|
323
|
+
* // Check key existence
|
|
324
|
+
* const map = new HashMap<string, number>([
|
|
325
|
+
* ['a', 1],
|
|
326
|
+
* ['b', 2]
|
|
327
|
+
* ]);
|
|
328
|
+
*
|
|
329
|
+
* console.log(map.has('a')); // true;
|
|
330
|
+
* console.log(map.has('z')); // false;
|
|
582
331
|
*/
|
|
583
332
|
override has(key: K): boolean {
|
|
584
333
|
if (this._isObjKey(key)) return this.objMap.has(key);
|
|
@@ -591,52 +340,17 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
591
340
|
* @remarks Time O(1), Space O(1)
|
|
592
341
|
* @param key - Key to delete.
|
|
593
342
|
* @returns True if the key was found and removed.
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
* @example
|
|
634
|
-
* // Remove entries by key
|
|
635
|
-
* const map = new HashMap<string, number>([['x', 10], ['y', 20], ['z', 30]]);
|
|
636
|
-
*
|
|
637
|
-
* console.log(map.delete('y')); // true;
|
|
638
|
-
* console.log(map.has('y')); // false;
|
|
639
|
-
* console.log(map.size); // 2;
|
|
343
|
+
* @example
|
|
344
|
+
* // Remove entries by key
|
|
345
|
+
* const map = new HashMap<string, number>([
|
|
346
|
+
* ['x', 10],
|
|
347
|
+
* ['y', 20],
|
|
348
|
+
* ['z', 30]
|
|
349
|
+
* ]);
|
|
350
|
+
*
|
|
351
|
+
* console.log(map.delete('y')); // true;
|
|
352
|
+
* console.log(map.has('y')); // false;
|
|
353
|
+
* console.log(map.size); // 2;
|
|
640
354
|
*/
|
|
641
355
|
delete(key: K): boolean {
|
|
642
356
|
if (this._isObjKey(key)) {
|
|
@@ -669,49 +383,12 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
669
383
|
* Deep clone this map, preserving hashing behavior.
|
|
670
384
|
* @remarks Time O(N), Space O(N)
|
|
671
385
|
* @returns A new map with the same content.
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
* @example
|
|
710
|
-
* // Create independent copy
|
|
711
|
-
* const map = new HashMap<string, number>([['a', 1]]);
|
|
712
|
-
* const copy = map.clone();
|
|
713
|
-
* copy.set('a', 99);
|
|
714
|
-
* console.log(map.get('a')); // 1;
|
|
386
|
+
* @example
|
|
387
|
+
* // Create independent copy
|
|
388
|
+
* const map = new HashMap<string, number>([['a', 1]]);
|
|
389
|
+
* const copy = map.clone();
|
|
390
|
+
* copy.set('a', 99);
|
|
391
|
+
* console.log(map.get('a')); // 1;
|
|
715
392
|
*/
|
|
716
393
|
clone(): this {
|
|
717
394
|
const opts = { hashFn: this._hashFn, toEntryFn: this._toEntryFn };
|
|
@@ -725,52 +402,16 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
725
402
|
* @param callbackfn - Mapping function (key, value, index, map) → newValue.
|
|
726
403
|
* @param [thisArg] - Value for `this` inside the callback.
|
|
727
404
|
* @returns A new map with transformed values.
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
* @example
|
|
768
|
-
* // Transform all values
|
|
769
|
-
* const prices = new HashMap<string, number>([['apple', 1], ['banana', 2]]);
|
|
770
|
-
*
|
|
771
|
-
* const doubled = prices.map(v => (v ?? 0) * 2);
|
|
772
|
-
* console.log(doubled.get('apple')); // 2;
|
|
773
|
-
* console.log(doubled.get('banana')); // 4;
|
|
405
|
+
* @example
|
|
406
|
+
* // Transform all values
|
|
407
|
+
* const prices = new HashMap<string, number>([
|
|
408
|
+
* ['apple', 1],
|
|
409
|
+
* ['banana', 2]
|
|
410
|
+
* ]);
|
|
411
|
+
*
|
|
412
|
+
* const doubled = prices.map(v => (v ?? 0) * 2);
|
|
413
|
+
* console.log(doubled.get('apple')); // 2;
|
|
414
|
+
* console.log(doubled.get('banana')); // 4;
|
|
774
415
|
*/
|
|
775
416
|
map<VM>(callbackfn: EntryCallback<K, V, VM>, thisArg?: unknown): HashMap<K, VM> {
|
|
776
417
|
const out = this._createLike<K, VM, [K, VM]>() as unknown as HashMap<K, VM>;
|
|
@@ -785,72 +426,32 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
785
426
|
* @param predicate - Predicate (key, value, index, map) → boolean.
|
|
786
427
|
* @param [thisArg] - Value for `this` inside the predicate.
|
|
787
428
|
* @returns A new map containing entries that satisfied the predicate.
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
* @example
|
|
828
|
-
* // HashMap iteration and filter operations
|
|
829
|
-
* const map = new HashMap<number, string>([
|
|
830
|
-
* [1, 'Alice'],
|
|
831
|
-
* [2, 'Bob'],
|
|
832
|
-
* [3, 'Charlie'],
|
|
833
|
-
* [4, 'Diana'],
|
|
834
|
-
* [5, 'Eve']
|
|
835
|
-
* ]);
|
|
836
|
-
*
|
|
837
|
-
* // Iterate through entries
|
|
838
|
-
* const entries: [number, string][] = [];
|
|
839
|
-
* for (const [key, value] of map) {
|
|
840
|
-
* entries.push([key, value]);
|
|
841
|
-
* }
|
|
842
|
-
* console.log(entries); // length: 5;
|
|
843
|
-
*
|
|
844
|
-
* // Filter operation (for iteration with collection methods)
|
|
845
|
-
* const filtered = [...map].filter(([key]) => key > 2);
|
|
846
|
-
* console.log(filtered.length); // 3;
|
|
847
|
-
*
|
|
848
|
-
* // Map operation
|
|
849
|
-
* const values = [...map.values()].map(v => v.length);
|
|
850
|
-
* console.log(values); // contains 3; // 'Bob', 'Eve'
|
|
851
|
-
* console.log(values); // contains 7;
|
|
429
|
+
* @example
|
|
430
|
+
* // HashMap iteration and filter operations
|
|
431
|
+
* const map = new HashMap<number, string>([
|
|
432
|
+
* [1, 'Alice'],
|
|
433
|
+
* [2, 'Bob'],
|
|
434
|
+
* [3, 'Charlie'],
|
|
435
|
+
* [4, 'Diana'],
|
|
436
|
+
* [5, 'Eve']
|
|
437
|
+
* ]);
|
|
438
|
+
*
|
|
439
|
+
* // Iterate through entries
|
|
440
|
+
* const entries: [number, string][] = [];
|
|
441
|
+
* for (const [key, value] of map) {
|
|
442
|
+
* entries.push([key, value]);
|
|
443
|
+
* }
|
|
444
|
+
* console.log(entries); // length: 5;
|
|
445
|
+
*
|
|
446
|
+
* // Filter operation (for iteration with collection methods)
|
|
447
|
+
* const filtered = [...map].filter(([key]) => key > 2);
|
|
448
|
+
* console.log(filtered.length); // 3;
|
|
449
|
+
*
|
|
450
|
+
* // Map operation
|
|
451
|
+
* const values = [...map.values()].map(v => v.length);
|
|
452
|
+
* console.log(values); // contains 3; // 'Bob', 'Eve'
|
|
453
|
+
* console.log(values); // contains 7;
|
|
852
454
|
*/
|
|
853
|
-
|
|
854
455
|
filter(predicate: EntryCallback<K, V, boolean>, thisArg?: unknown): this {
|
|
855
456
|
const out = this._createLike<K, V, [K, V]>();
|
|
856
457
|
let index = 0;
|
|
@@ -868,7 +469,10 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
868
469
|
* @param [options] - Options forwarded to the constructor.
|
|
869
470
|
* @returns A like-kind map instance.
|
|
870
471
|
*/
|
|
871
|
-
protected _createLike<TK = K, TV = V, TR = [TK, TV]>(
|
|
472
|
+
protected _createLike<TK = K, TV = V, TR = [TK, TV]>(
|
|
473
|
+
entries: Iterable<[TK, TV] | TR> = [],
|
|
474
|
+
options?: Record<string, unknown>
|
|
475
|
+
): this {
|
|
872
476
|
const Ctor = this.constructor as new (e?: Iterable<[TK, TV] | TR>, o?: Record<string, unknown>) => this;
|
|
873
477
|
return new Ctor(entries, options);
|
|
874
478
|
}
|
|
@@ -894,7 +498,6 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
894
498
|
|
|
895
499
|
protected _getNoObjKey(key: K): string {
|
|
896
500
|
const keyType = typeof key;
|
|
897
|
-
|
|
898
501
|
let strKey: string;
|
|
899
502
|
if (keyType !== 'string' && keyType !== 'number' && keyType !== 'symbol') {
|
|
900
503
|
strKey = this._hashFn(key);
|
|
@@ -931,14 +534,12 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
931
534
|
super();
|
|
932
535
|
this._sentinel = <HashMapLinkedNode<K, V>>{};
|
|
933
536
|
this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;
|
|
934
|
-
|
|
935
537
|
if (options) {
|
|
936
538
|
const { hashFn, objHashFn, toEntryFn } = options;
|
|
937
539
|
if (hashFn) this._hashFn = hashFn;
|
|
938
540
|
if (objHashFn) this._objHashFn = objHashFn;
|
|
939
541
|
if (toEntryFn) this._toEntryFn = toEntryFn;
|
|
940
542
|
}
|
|
941
|
-
|
|
942
543
|
if (entryOrRawElements) this.setMany(entryOrRawElements);
|
|
943
544
|
}
|
|
944
545
|
|
|
@@ -996,18 +597,12 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
996
597
|
return this._tail;
|
|
997
598
|
}
|
|
998
599
|
|
|
999
|
-
protected readonly _toEntryFn?: (rawElement: R) => [K, V] = (rawElement: R) => {
|
|
1000
|
-
if (this.isEntry(rawElement)) {
|
|
1001
|
-
return rawElement;
|
|
1002
|
-
}
|
|
1003
|
-
raise(TypeError, ERR.invalidArgument('If elements do not adhere to [key, value], provide options.toEntryFn to transform raw records.', 'HashMap'));
|
|
1004
|
-
};
|
|
1005
|
-
|
|
1006
600
|
get toEntryFn() {
|
|
1007
601
|
return this._toEntryFn;
|
|
1008
602
|
}
|
|
1009
603
|
|
|
1010
604
|
protected _size = 0;
|
|
605
|
+
|
|
1011
606
|
get size() {
|
|
1012
607
|
return this._size;
|
|
1013
608
|
}
|
|
@@ -1068,7 +663,6 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1068
663
|
set(key: K, value?: V): this {
|
|
1069
664
|
let node: HashMapLinkedNode<K, V | undefined> | undefined;
|
|
1070
665
|
const isNewKey = !this.has(key);
|
|
1071
|
-
|
|
1072
666
|
if (isWeakKey(key)) {
|
|
1073
667
|
const hash = this._objHashFn(key);
|
|
1074
668
|
node = this.objMap.get(hash);
|
|
@@ -1087,7 +681,6 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1087
681
|
node.value = value;
|
|
1088
682
|
}
|
|
1089
683
|
}
|
|
1090
|
-
|
|
1091
684
|
if (node && isNewKey) {
|
|
1092
685
|
if (this._size === 0) {
|
|
1093
686
|
this._head = node;
|
|
@@ -1100,7 +693,6 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1100
693
|
this._sentinel.prev = node;
|
|
1101
694
|
this._size++;
|
|
1102
695
|
}
|
|
1103
|
-
|
|
1104
696
|
return this;
|
|
1105
697
|
}
|
|
1106
698
|
|
|
@@ -1259,6 +851,19 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1259
851
|
return out;
|
|
1260
852
|
}
|
|
1261
853
|
|
|
854
|
+
protected readonly _toEntryFn?: (rawElement: R) => [K, V] = (rawElement: R) => {
|
|
855
|
+
if (this.isEntry(rawElement)) {
|
|
856
|
+
return rawElement;
|
|
857
|
+
}
|
|
858
|
+
raise(
|
|
859
|
+
TypeError,
|
|
860
|
+
ERR.invalidArgument(
|
|
861
|
+
'If elements do not adhere to [key, value], provide options.toEntryFn to transform raw records.',
|
|
862
|
+
'HashMap'
|
|
863
|
+
)
|
|
864
|
+
);
|
|
865
|
+
};
|
|
866
|
+
|
|
1262
867
|
protected *_getIterator(): IterableIterator<[K, V]> {
|
|
1263
868
|
let node = this.head;
|
|
1264
869
|
while (node !== this._sentinel) {
|
|
@@ -1276,20 +881,20 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1276
881
|
const hash = this._hashFn(key as K);
|
|
1277
882
|
delete this._noObjMap[hash];
|
|
1278
883
|
}
|
|
1279
|
-
|
|
1280
884
|
// Remove from linked list
|
|
1281
885
|
const { prev, next } = node;
|
|
1282
886
|
prev.next = next;
|
|
1283
887
|
next.prev = prev;
|
|
1284
|
-
|
|
1285
888
|
if (node === this.head) this._head = next;
|
|
1286
889
|
if (node === this.tail) this._tail = prev;
|
|
1287
|
-
|
|
1288
890
|
this._size -= 1;
|
|
1289
891
|
return true;
|
|
1290
892
|
}
|
|
1291
893
|
|
|
1292
|
-
protected _createLike<TK = K, TV = V, TR = [TK, TV]>(
|
|
894
|
+
protected _createLike<TK = K, TV = V, TR = [TK, TV]>(
|
|
895
|
+
entries: Iterable<[TK, TV] | TR> = [],
|
|
896
|
+
options?: Record<string, unknown>
|
|
897
|
+
): this {
|
|
1293
898
|
const Ctor = this.constructor as new (e?: Iterable<[TK, TV] | TR>, o?: Record<string, unknown>) => this;
|
|
1294
899
|
return new Ctor(entries, options);
|
|
1295
900
|
}
|