data-structure-typed 2.6.0 → 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/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 +23 -23
- 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/package.json +45 -46
- package/src/common/error.ts +15 -32
- package/src/common/index.ts +0 -3
- package/src/data-structures/base/iterable-element-base.ts +0 -3
- package/src/data-structures/base/linear-base.ts +2 -36
- package/src/data-structures/binary-tree/avl-tree.ts +31 -529
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +47 -572
- package/src/data-structures/binary-tree/binary-tree.ts +326 -1311
- package/src/data-structures/binary-tree/bst.ts +158 -1082
- package/src/data-structures/binary-tree/red-black-tree.ts +451 -1290
- package/src/data-structures/binary-tree/segment-tree.ts +73 -351
- package/src/data-structures/binary-tree/tree-map.ts +462 -5124
- package/src/data-structures/binary-tree/tree-multi-map.ts +302 -4914
- package/src/data-structures/binary-tree/tree-multi-set.ts +284 -3972
- package/src/data-structures/binary-tree/tree-set.ts +338 -4836
- package/src/data-structures/graph/abstract-graph.ts +98 -167
- package/src/data-structures/graph/directed-graph.ts +137 -562
- package/src/data-structures/graph/map-graph.ts +0 -3
- package/src/data-structures/graph/undirected-graph.ts +132 -511
- package/src/data-structures/hash/hash-map.ts +154 -582
- package/src/data-structures/heap/heap.ts +200 -795
- package/src/data-structures/linked-list/doubly-linked-list.ts +121 -865
- package/src/data-structures/linked-list/singly-linked-list.ts +122 -794
- package/src/data-structures/linked-list/skip-linked-list.ts +211 -918
- package/src/data-structures/matrix/matrix.ts +179 -518
- 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 +214 -882
- package/src/data-structures/queue/queue.ts +102 -625
- package/src/data-structures/stack/stack.ts +76 -505
- package/src/data-structures/trie/trie.ts +98 -628
- 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,50 +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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
* @example
|
|
215
|
-
* // Check if empty
|
|
216
|
-
* const map = new HashMap();
|
|
217
|
-
* console.log(map.isEmpty()); // true;
|
|
180
|
+
* @example
|
|
181
|
+
* // Check if empty
|
|
182
|
+
* const map = new HashMap();
|
|
183
|
+
* console.log(map.isEmpty()); // true;
|
|
218
184
|
*/
|
|
219
185
|
isEmpty(): boolean {
|
|
220
186
|
return this._size === 0;
|
|
@@ -224,51 +190,14 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
224
190
|
* Remove all entries and reset counters.
|
|
225
191
|
* @remarks Time O(N), Space O(1)
|
|
226
192
|
* @returns void
|
|
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
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
* @example
|
|
268
|
-
* // Remove all entries
|
|
269
|
-
* const map = new HashMap<string, number>([['a', 1], ['b', 2]]);
|
|
270
|
-
* map.clear();
|
|
271
|
-
* 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;
|
|
272
201
|
*/
|
|
273
202
|
clear(): void {
|
|
274
203
|
this._store = {};
|
|
@@ -291,108 +220,24 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
291
220
|
* @param key - Key.
|
|
292
221
|
* @param value - Value.
|
|
293
222
|
* @returns True when the operation succeeds.
|
|
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
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
* @example
|
|
379
|
-
* // basic HashMap creation and set operation
|
|
380
|
-
* // Create a simple HashMap with key-value pairs
|
|
381
|
-
* const map = new HashMap<number, string>([
|
|
382
|
-
* [1, 'one'],
|
|
383
|
-
* [2, 'two'],
|
|
384
|
-
* [3, 'three']
|
|
385
|
-
* ]);
|
|
386
|
-
*
|
|
387
|
-
* // Verify size
|
|
388
|
-
* console.log(map.size); // 3;
|
|
389
|
-
*
|
|
390
|
-
* // Set a new key-value pair
|
|
391
|
-
* map.set(4, 'four');
|
|
392
|
-
* console.log(map.size); // 4;
|
|
393
|
-
*
|
|
394
|
-
* // Verify entries
|
|
395
|
-
* 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;
|
|
396
241
|
*/
|
|
397
242
|
set(key: K, value: V): this {
|
|
398
243
|
if (this._isObjKey(key)) {
|
|
@@ -411,51 +256,15 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
411
256
|
* @remarks Time O(N), Space O(N)
|
|
412
257
|
* @param entryOrRawElements - Iterable of entries or raw elements to insert.
|
|
413
258
|
* @returns Array of per-entry results.
|
|
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
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
* @example
|
|
455
|
-
* // Add multiple entries
|
|
456
|
-
* const map = new HashMap<string, number>();
|
|
457
|
-
* map.setMany([['a', 1], ['b', 2], ['c', 3]]);
|
|
458
|
-
* 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;
|
|
459
268
|
*/
|
|
460
269
|
setMany(entryOrRawElements: Iterable<R | [K, V]>): boolean[] {
|
|
461
270
|
const results: boolean[] = [];
|
|
@@ -477,69 +286,27 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
477
286
|
* @remarks Time O(1), Space O(1)
|
|
478
287
|
* @param key - Key to look up.
|
|
479
288
|
* @returns Value or undefined.
|
|
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
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
* @example
|
|
523
|
-
* // HashMap get and has operations
|
|
524
|
-
* const map = new HashMap<string, number>([
|
|
525
|
-
* ['apple', 1],
|
|
526
|
-
* ['banana', 2],
|
|
527
|
-
* ['cherry', 3]
|
|
528
|
-
* ]);
|
|
529
|
-
*
|
|
530
|
-
* // Check if key exists
|
|
531
|
-
* console.log(map.has('apple')); // true;
|
|
532
|
-
* console.log(map.has('date')); // false;
|
|
533
|
-
*
|
|
534
|
-
* // Get value by key
|
|
535
|
-
* console.log(map.get('banana')); // 2;
|
|
536
|
-
* console.log(map.get('grape')); // undefined;
|
|
537
|
-
*
|
|
538
|
-
* // Get all keys and values
|
|
539
|
-
* const keys = [...map.keys()];
|
|
540
|
-
* const values = [...map.values()];
|
|
541
|
-
* console.log(keys); // contains 'apple';
|
|
542
|
-
* 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;
|
|
543
310
|
*/
|
|
544
311
|
override get(key: K): V | undefined {
|
|
545
312
|
if (this._isObjKey(key)) return this.objMap.get(key);
|
|
@@ -552,54 +319,15 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
552
319
|
* @remarks Time O(1), Space O(1)
|
|
553
320
|
* @param key - Key to test.
|
|
554
321
|
* @returns True if present.
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
* @example
|
|
598
|
-
* // Check key existence
|
|
599
|
-
* const map = new HashMap<string, number>([['a', 1], ['b', 2]]);
|
|
600
|
-
*
|
|
601
|
-
* console.log(map.has('a')); // true;
|
|
602
|
-
* 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;
|
|
603
331
|
*/
|
|
604
332
|
override has(key: K): boolean {
|
|
605
333
|
if (this._isObjKey(key)) return this.objMap.has(key);
|
|
@@ -612,55 +340,17 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
612
340
|
* @remarks Time O(1), Space O(1)
|
|
613
341
|
* @param key - Key to delete.
|
|
614
342
|
* @returns True if the key was found and removed.
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
* @example
|
|
658
|
-
* // Remove entries by key
|
|
659
|
-
* const map = new HashMap<string, number>([['x', 10], ['y', 20], ['z', 30]]);
|
|
660
|
-
*
|
|
661
|
-
* console.log(map.delete('y')); // true;
|
|
662
|
-
* console.log(map.has('y')); // false;
|
|
663
|
-
* 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;
|
|
664
354
|
*/
|
|
665
355
|
delete(key: K): boolean {
|
|
666
356
|
if (this._isObjKey(key)) {
|
|
@@ -693,52 +383,12 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
693
383
|
* Deep clone this map, preserving hashing behavior.
|
|
694
384
|
* @remarks Time O(N), Space O(N)
|
|
695
385
|
* @returns A new map with the same content.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
* @example
|
|
737
|
-
* // Create independent copy
|
|
738
|
-
* const map = new HashMap<string, number>([['a', 1]]);
|
|
739
|
-
* const copy = map.clone();
|
|
740
|
-
* copy.set('a', 99);
|
|
741
|
-
* 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;
|
|
742
392
|
*/
|
|
743
393
|
clone(): this {
|
|
744
394
|
const opts = { hashFn: this._hashFn, toEntryFn: this._toEntryFn };
|
|
@@ -752,55 +402,16 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
752
402
|
* @param callbackfn - Mapping function (key, value, index, map) → newValue.
|
|
753
403
|
* @param [thisArg] - Value for `this` inside the callback.
|
|
754
404
|
* @returns A new map with transformed values.
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
* @example
|
|
798
|
-
* // Transform all values
|
|
799
|
-
* const prices = new HashMap<string, number>([['apple', 1], ['banana', 2]]);
|
|
800
|
-
*
|
|
801
|
-
* const doubled = prices.map(v => (v ?? 0) * 2);
|
|
802
|
-
* console.log(doubled.get('apple')); // 2;
|
|
803
|
-
* 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;
|
|
804
415
|
*/
|
|
805
416
|
map<VM>(callbackfn: EntryCallback<K, V, VM>, thisArg?: unknown): HashMap<K, VM> {
|
|
806
417
|
const out = this._createLike<K, VM, [K, VM]>() as unknown as HashMap<K, VM>;
|
|
@@ -815,75 +426,32 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
815
426
|
* @param predicate - Predicate (key, value, index, map) → boolean.
|
|
816
427
|
* @param [thisArg] - Value for `this` inside the predicate.
|
|
817
428
|
* @returns A new map containing entries that satisfied the predicate.
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
* @example
|
|
861
|
-
* // HashMap iteration and filter operations
|
|
862
|
-
* const map = new HashMap<number, string>([
|
|
863
|
-
* [1, 'Alice'],
|
|
864
|
-
* [2, 'Bob'],
|
|
865
|
-
* [3, 'Charlie'],
|
|
866
|
-
* [4, 'Diana'],
|
|
867
|
-
* [5, 'Eve']
|
|
868
|
-
* ]);
|
|
869
|
-
*
|
|
870
|
-
* // Iterate through entries
|
|
871
|
-
* const entries: [number, string][] = [];
|
|
872
|
-
* for (const [key, value] of map) {
|
|
873
|
-
* entries.push([key, value]);
|
|
874
|
-
* }
|
|
875
|
-
* console.log(entries); // length: 5;
|
|
876
|
-
*
|
|
877
|
-
* // Filter operation (for iteration with collection methods)
|
|
878
|
-
* const filtered = [...map].filter(([key]) => key > 2);
|
|
879
|
-
* console.log(filtered.length); // 3;
|
|
880
|
-
*
|
|
881
|
-
* // Map operation
|
|
882
|
-
* const values = [...map.values()].map(v => v.length);
|
|
883
|
-
* console.log(values); // contains 3; // 'Bob', 'Eve'
|
|
884
|
-
* 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;
|
|
885
454
|
*/
|
|
886
|
-
|
|
887
455
|
filter(predicate: EntryCallback<K, V, boolean>, thisArg?: unknown): this {
|
|
888
456
|
const out = this._createLike<K, V, [K, V]>();
|
|
889
457
|
let index = 0;
|
|
@@ -901,7 +469,10 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
901
469
|
* @param [options] - Options forwarded to the constructor.
|
|
902
470
|
* @returns A like-kind map instance.
|
|
903
471
|
*/
|
|
904
|
-
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 {
|
|
905
476
|
const Ctor = this.constructor as new (e?: Iterable<[TK, TV] | TR>, o?: Record<string, unknown>) => this;
|
|
906
477
|
return new Ctor(entries, options);
|
|
907
478
|
}
|
|
@@ -927,7 +498,6 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
927
498
|
|
|
928
499
|
protected _getNoObjKey(key: K): string {
|
|
929
500
|
const keyType = typeof key;
|
|
930
|
-
|
|
931
501
|
let strKey: string;
|
|
932
502
|
if (keyType !== 'string' && keyType !== 'number' && keyType !== 'symbol') {
|
|
933
503
|
strKey = this._hashFn(key);
|
|
@@ -964,14 +534,12 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
964
534
|
super();
|
|
965
535
|
this._sentinel = <HashMapLinkedNode<K, V>>{};
|
|
966
536
|
this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;
|
|
967
|
-
|
|
968
537
|
if (options) {
|
|
969
538
|
const { hashFn, objHashFn, toEntryFn } = options;
|
|
970
539
|
if (hashFn) this._hashFn = hashFn;
|
|
971
540
|
if (objHashFn) this._objHashFn = objHashFn;
|
|
972
541
|
if (toEntryFn) this._toEntryFn = toEntryFn;
|
|
973
542
|
}
|
|
974
|
-
|
|
975
543
|
if (entryOrRawElements) this.setMany(entryOrRawElements);
|
|
976
544
|
}
|
|
977
545
|
|
|
@@ -1029,18 +597,12 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1029
597
|
return this._tail;
|
|
1030
598
|
}
|
|
1031
599
|
|
|
1032
|
-
protected readonly _toEntryFn?: (rawElement: R) => [K, V] = (rawElement: R) => {
|
|
1033
|
-
if (this.isEntry(rawElement)) {
|
|
1034
|
-
return rawElement;
|
|
1035
|
-
}
|
|
1036
|
-
raise(TypeError, ERR.invalidArgument('If elements do not adhere to [key, value], provide options.toEntryFn to transform raw records.', 'HashMap'));
|
|
1037
|
-
};
|
|
1038
|
-
|
|
1039
600
|
get toEntryFn() {
|
|
1040
601
|
return this._toEntryFn;
|
|
1041
602
|
}
|
|
1042
603
|
|
|
1043
604
|
protected _size = 0;
|
|
605
|
+
|
|
1044
606
|
get size() {
|
|
1045
607
|
return this._size;
|
|
1046
608
|
}
|
|
@@ -1101,7 +663,6 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1101
663
|
set(key: K, value?: V): this {
|
|
1102
664
|
let node: HashMapLinkedNode<K, V | undefined> | undefined;
|
|
1103
665
|
const isNewKey = !this.has(key);
|
|
1104
|
-
|
|
1105
666
|
if (isWeakKey(key)) {
|
|
1106
667
|
const hash = this._objHashFn(key);
|
|
1107
668
|
node = this.objMap.get(hash);
|
|
@@ -1120,7 +681,6 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1120
681
|
node.value = value;
|
|
1121
682
|
}
|
|
1122
683
|
}
|
|
1123
|
-
|
|
1124
684
|
if (node && isNewKey) {
|
|
1125
685
|
if (this._size === 0) {
|
|
1126
686
|
this._head = node;
|
|
@@ -1133,7 +693,6 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1133
693
|
this._sentinel.prev = node;
|
|
1134
694
|
this._size++;
|
|
1135
695
|
}
|
|
1136
|
-
|
|
1137
696
|
return this;
|
|
1138
697
|
}
|
|
1139
698
|
|
|
@@ -1292,6 +851,19 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1292
851
|
return out;
|
|
1293
852
|
}
|
|
1294
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
|
+
|
|
1295
867
|
protected *_getIterator(): IterableIterator<[K, V]> {
|
|
1296
868
|
let node = this.head;
|
|
1297
869
|
while (node !== this._sentinel) {
|
|
@@ -1309,20 +881,20 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
1309
881
|
const hash = this._hashFn(key as K);
|
|
1310
882
|
delete this._noObjMap[hash];
|
|
1311
883
|
}
|
|
1312
|
-
|
|
1313
884
|
// Remove from linked list
|
|
1314
885
|
const { prev, next } = node;
|
|
1315
886
|
prev.next = next;
|
|
1316
887
|
next.prev = prev;
|
|
1317
|
-
|
|
1318
888
|
if (node === this.head) this._head = next;
|
|
1319
889
|
if (node === this.tail) this._tail = prev;
|
|
1320
|
-
|
|
1321
890
|
this._size -= 1;
|
|
1322
891
|
return true;
|
|
1323
892
|
}
|
|
1324
893
|
|
|
1325
|
-
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 {
|
|
1326
898
|
const Ctor = this.constructor as new (e?: Iterable<[TK, TV] | TR>, o?: Record<string, unknown>) => this;
|
|
1327
899
|
return new Ctor(entries, options);
|
|
1328
900
|
}
|