binary-tree-typed 2.4.5 → 2.5.0
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/README.md +0 -84
- package/dist/cjs/index.cjs +867 -404
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +864 -401
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +867 -404
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +864 -401
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +429 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +212 -32
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/directed-graph.d.ts +219 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +204 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +272 -65
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/umd/binary-tree-typed.js +860 -397
- package/dist/umd/binary-tree-typed.js.map +1 -1
- package/dist/umd/binary-tree-typed.min.js +2 -2
- package/dist/umd/binary-tree-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +4 -5
- package/src/data-structures/binary-tree/avl-tree.ts +134 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +302 -247
- package/src/data-structures/binary-tree/binary-tree.ts +429 -79
- package/src/data-structures/binary-tree/bst.ts +335 -34
- package/src/data-structures/binary-tree/red-black-tree.ts +290 -97
- package/src/data-structures/binary-tree/segment-tree.ts +372 -248
- package/src/data-structures/binary-tree/tree-map.ts +1284 -6
- package/src/data-structures/binary-tree/tree-multi-map.ts +1094 -211
- package/src/data-structures/binary-tree/tree-multi-set.ts +858 -65
- package/src/data-structures/binary-tree/tree-set.ts +1136 -9
- package/src/data-structures/graph/directed-graph.ts +219 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +204 -59
- package/src/data-structures/hash/hash-map.ts +230 -77
- package/src/data-structures/heap/heap.ts +287 -99
- package/src/data-structures/heap/max-heap.ts +46 -0
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
- package/src/data-structures/matrix/matrix.ts +416 -12
- package/src/data-structures/priority-queue/max-priority-queue.ts +57 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +272 -65
- package/src/data-structures/queue/queue.ts +211 -42
- package/src/data-structures/stack/stack.ts +174 -32
- package/src/data-structures/trie/trie.ts +213 -43
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
|
@@ -77,65 +77,6 @@ export class UndirectedEdge<E = number> extends AbstractEdge<E> {
|
|
|
77
77
|
* console.log(neighborsA[0].key); // 'B';
|
|
78
78
|
* console.log(neighborsA[1].key); // 'C';
|
|
79
79
|
* @example
|
|
80
|
-
* // UndirectedGraph deleteEdge and vertex operations
|
|
81
|
-
* const graph = new UndirectedGraph<string>();
|
|
82
|
-
*
|
|
83
|
-
* // Build a simple undirected graph
|
|
84
|
-
* graph.addVertex('X');
|
|
85
|
-
* graph.addVertex('Y');
|
|
86
|
-
* graph.addVertex('Z');
|
|
87
|
-
* graph.addEdge('X', 'Y', 1);
|
|
88
|
-
* graph.addEdge('Y', 'Z', 2);
|
|
89
|
-
* graph.addEdge('X', 'Z', 3);
|
|
90
|
-
*
|
|
91
|
-
* // Delete an edge
|
|
92
|
-
* graph.deleteEdge('X', 'Y');
|
|
93
|
-
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
94
|
-
*
|
|
95
|
-
* // Bidirectional deletion confirmed
|
|
96
|
-
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
97
|
-
*
|
|
98
|
-
* // Other edges should remain
|
|
99
|
-
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
100
|
-
* console.log(graph.hasEdge('Z', 'Y')); // true;
|
|
101
|
-
*
|
|
102
|
-
* // Delete a vertex
|
|
103
|
-
* graph.deleteVertex('Y');
|
|
104
|
-
* console.log(graph.hasVertex('Y')); // false;
|
|
105
|
-
* console.log(graph.size); // 2;
|
|
106
|
-
* @example
|
|
107
|
-
* // UndirectedGraph connectivity and neighbors
|
|
108
|
-
* const graph = new UndirectedGraph<string>();
|
|
109
|
-
*
|
|
110
|
-
* // Build a friendship network
|
|
111
|
-
* const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
|
|
112
|
-
* for (const person of people) {
|
|
113
|
-
* graph.addVertex(person);
|
|
114
|
-
* }
|
|
115
|
-
*
|
|
116
|
-
* // Add friendships (undirected edges)
|
|
117
|
-
* graph.addEdge('Alice', 'Bob', 1);
|
|
118
|
-
* graph.addEdge('Alice', 'Charlie', 1);
|
|
119
|
-
* graph.addEdge('Bob', 'Diana', 1);
|
|
120
|
-
* graph.addEdge('Charlie', 'Eve', 1);
|
|
121
|
-
* graph.addEdge('Diana', 'Eve', 1);
|
|
122
|
-
*
|
|
123
|
-
* // Get friends of each person
|
|
124
|
-
* const aliceFriends = graph.getNeighbors('Alice');
|
|
125
|
-
* console.log(aliceFriends[0].key); // 'Bob';
|
|
126
|
-
* console.log(aliceFriends[1].key); // 'Charlie';
|
|
127
|
-
* console.log(aliceFriends.length); // 2;
|
|
128
|
-
*
|
|
129
|
-
* const dianaFriends = graph.getNeighbors('Diana');
|
|
130
|
-
* console.log(dianaFriends[0].key); // 'Bob';
|
|
131
|
-
* console.log(dianaFriends[1].key); // 'Eve';
|
|
132
|
-
* console.log(dianaFriends.length); // 2;
|
|
133
|
-
*
|
|
134
|
-
* // Verify bidirectional friendship
|
|
135
|
-
* const bobFriends = graph.getNeighbors('Bob');
|
|
136
|
-
* console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
|
|
137
|
-
* console.log(bobFriends[1].key); // 'Diana';
|
|
138
|
-
* @example
|
|
139
80
|
* // UndirectedGraph for social network connectivity analysis
|
|
140
81
|
* interface Person {
|
|
141
82
|
* id: number;
|
|
@@ -285,6 +226,21 @@ export class UndirectedGraph<
|
|
|
285
226
|
* @param v2 - The other vertex or key.
|
|
286
227
|
* @returns Edge instance or `undefined`.
|
|
287
228
|
* @remarks Time O(1) avg, Space O(1)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
* @example
|
|
238
|
+
* // Get edge between vertices
|
|
239
|
+
* const g = new UndirectedGraph();
|
|
240
|
+
* g.addVertex('A');
|
|
241
|
+
* g.addVertex('B');
|
|
242
|
+
* g.addEdge('A', 'B', 7);
|
|
243
|
+
* console.log(g.getEdge('A', 'B')?.weight); // 7;
|
|
288
244
|
*/
|
|
289
245
|
getEdge(v1: VO | VertexKey | undefined, v2: VO | VertexKey | undefined): EO | undefined {
|
|
290
246
|
let edgeMap: EO[] | undefined = [];
|
|
@@ -334,6 +290,44 @@ export class UndirectedGraph<
|
|
|
334
290
|
* @param otherSideVertexKey - Required second endpoint when deleting by pair.
|
|
335
291
|
* @returns Removed edge or `undefined`.
|
|
336
292
|
* @remarks Time O(1) avg, Space O(1)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
* @example
|
|
305
|
+
* // UndirectedGraph deleteEdge and vertex operations
|
|
306
|
+
* const graph = new UndirectedGraph<string>();
|
|
307
|
+
*
|
|
308
|
+
* // Build a simple undirected graph
|
|
309
|
+
* graph.addVertex('X');
|
|
310
|
+
* graph.addVertex('Y');
|
|
311
|
+
* graph.addVertex('Z');
|
|
312
|
+
* graph.addEdge('X', 'Y', 1);
|
|
313
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
314
|
+
* graph.addEdge('X', 'Z', 3);
|
|
315
|
+
*
|
|
316
|
+
* // Delete an edge
|
|
317
|
+
* graph.deleteEdge('X', 'Y');
|
|
318
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
319
|
+
*
|
|
320
|
+
* // Bidirectional deletion confirmed
|
|
321
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
322
|
+
*
|
|
323
|
+
* // Other edges should remain
|
|
324
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
325
|
+
* console.log(graph.hasEdge('Z', 'Y')); // true;
|
|
326
|
+
*
|
|
327
|
+
* // Delete a vertex
|
|
328
|
+
* graph.deleteVertex('Y');
|
|
329
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
330
|
+
* console.log(graph.size); // 2;
|
|
337
331
|
*/
|
|
338
332
|
deleteEdge(edgeOrOneSideVertexKey: EO | VertexKey, otherSideVertexKey?: VertexKey): EO | undefined {
|
|
339
333
|
let oneSide: VO | undefined, otherSide: VO | undefined;
|
|
@@ -361,6 +355,22 @@ export class UndirectedGraph<
|
|
|
361
355
|
* @param vertexOrKey - Vertex or key.
|
|
362
356
|
* @returns `true` if removed; otherwise `false`.
|
|
363
357
|
* @remarks Time O(deg), Space O(1)
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
* @example
|
|
367
|
+
* // Remove vertex and edges
|
|
368
|
+
* const g = new UndirectedGraph();
|
|
369
|
+
* g.addVertex('A');
|
|
370
|
+
* g.addVertex('B');
|
|
371
|
+
* g.addEdge('A', 'B');
|
|
372
|
+
* g.deleteVertex('A');
|
|
373
|
+
* console.log(g.hasVertex('A')); // false;
|
|
364
374
|
*/
|
|
365
375
|
deleteVertex(vertexOrKey: VO | VertexKey): boolean {
|
|
366
376
|
let vertexKey: VertexKey;
|
|
@@ -431,6 +441,21 @@ export class UndirectedGraph<
|
|
|
431
441
|
* Unique set of undirected edges across endpoints.
|
|
432
442
|
* @returns Array of edges.
|
|
433
443
|
* @remarks Time O(E), Space O(E)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
* @example
|
|
453
|
+
* // Get all edges
|
|
454
|
+
* const g = new UndirectedGraph();
|
|
455
|
+
* g.addVertex('A');
|
|
456
|
+
* g.addVertex('B');
|
|
457
|
+
* g.addEdge('A', 'B');
|
|
458
|
+
* console.log(g.edgeSet().length); // 1;
|
|
434
459
|
*/
|
|
435
460
|
edgeSet(): EO[] {
|
|
436
461
|
const edgeSet: Set<EO> = new Set();
|
|
@@ -442,6 +467,52 @@ export class UndirectedGraph<
|
|
|
442
467
|
return [...edgeSet];
|
|
443
468
|
}
|
|
444
469
|
|
|
470
|
+
/**
|
|
471
|
+
* UndirectedGraph connectivity and neighbors
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
* @example
|
|
484
|
+
* // UndirectedGraph connectivity and neighbors
|
|
485
|
+
* const graph = new UndirectedGraph<string>();
|
|
486
|
+
*
|
|
487
|
+
* // Build a friendship network
|
|
488
|
+
* const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
|
|
489
|
+
* for (const person of people) {
|
|
490
|
+
* graph.addVertex(person);
|
|
491
|
+
* }
|
|
492
|
+
*
|
|
493
|
+
* // Add friendships (undirected edges)
|
|
494
|
+
* graph.addEdge('Alice', 'Bob', 1);
|
|
495
|
+
* graph.addEdge('Alice', 'Charlie', 1);
|
|
496
|
+
* graph.addEdge('Bob', 'Diana', 1);
|
|
497
|
+
* graph.addEdge('Charlie', 'Eve', 1);
|
|
498
|
+
* graph.addEdge('Diana', 'Eve', 1);
|
|
499
|
+
*
|
|
500
|
+
* // Get friends of each person
|
|
501
|
+
* const aliceFriends = graph.getNeighbors('Alice');
|
|
502
|
+
* console.log(aliceFriends[0].key); // 'Bob';
|
|
503
|
+
* console.log(aliceFriends[1].key); // 'Charlie';
|
|
504
|
+
* console.log(aliceFriends.length); // 2;
|
|
505
|
+
*
|
|
506
|
+
* const dianaFriends = graph.getNeighbors('Diana');
|
|
507
|
+
* console.log(dianaFriends[0].key); // 'Bob';
|
|
508
|
+
* console.log(dianaFriends[1].key); // 'Eve';
|
|
509
|
+
* console.log(dianaFriends.length); // 2;
|
|
510
|
+
*
|
|
511
|
+
* // Verify bidirectional friendship
|
|
512
|
+
* const bobFriends = graph.getNeighbors('Bob');
|
|
513
|
+
* console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
|
|
514
|
+
* console.log(bobFriends[1].key); // 'Diana';
|
|
515
|
+
*/
|
|
445
516
|
getNeighbors(vertexOrKey: VO | VertexKey): VO[] {
|
|
446
517
|
const neighbors: VO[] = [];
|
|
447
518
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -506,6 +577,24 @@ export class UndirectedGraph<
|
|
|
506
577
|
* Tarjan-based bridge and articulation point detection.
|
|
507
578
|
* @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
|
|
508
579
|
* @remarks Time O(V + E), Space O(V + E)
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
* @example
|
|
589
|
+
* // Find articulation points and bridges
|
|
590
|
+
* const g = new UndirectedGraph();
|
|
591
|
+
* g.addVertex('A');
|
|
592
|
+
* g.addVertex('B');
|
|
593
|
+
* g.addVertex('C');
|
|
594
|
+
* g.addEdge('A', 'B');
|
|
595
|
+
* g.addEdge('B', 'C');
|
|
596
|
+
* const result = g.tarjan();
|
|
597
|
+
* console.log(result); // defined;
|
|
509
598
|
*/
|
|
510
599
|
tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; bridges: EO[]; cutVertices: VO[] } {
|
|
511
600
|
const dfnMap = new Map<VO, number>();
|
|
@@ -637,6 +726,25 @@ export class UndirectedGraph<
|
|
|
637
726
|
* Uses DFS with parent tracking.
|
|
638
727
|
* @returns `true` if a cycle exists, `false` otherwise.
|
|
639
728
|
* @remarks Time O(V + E), Space O(V)
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
* @example
|
|
738
|
+
* // Detect cycle
|
|
739
|
+
* const g = new UndirectedGraph();
|
|
740
|
+
* g.addVertex('A');
|
|
741
|
+
* g.addVertex('B');
|
|
742
|
+
* g.addVertex('C');
|
|
743
|
+
* g.addEdge('A', 'B');
|
|
744
|
+
* g.addEdge('B', 'C');
|
|
745
|
+
* console.log(g.hasCycle()); // false;
|
|
746
|
+
* g.addEdge('C', 'A');
|
|
747
|
+
* console.log(g.hasCycle()); // true;
|
|
640
748
|
*/
|
|
641
749
|
hasCycle(): boolean {
|
|
642
750
|
const visited = new Set<VO>();
|
|
@@ -665,6 +773,24 @@ export class UndirectedGraph<
|
|
|
665
773
|
* Get bridges discovered by `tarjan()`.
|
|
666
774
|
* @returns Array of edges that are bridges.
|
|
667
775
|
* @remarks Time O(B), Space O(1)
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
* @example
|
|
785
|
+
* // Find bridge edges
|
|
786
|
+
* const g = new UndirectedGraph();
|
|
787
|
+
* g.addVertex('A');
|
|
788
|
+
* g.addVertex('B');
|
|
789
|
+
* g.addVertex('C');
|
|
790
|
+
* g.addEdge('A', 'B');
|
|
791
|
+
* g.addEdge('B', 'C');
|
|
792
|
+
* const bridges = g.getBridges();
|
|
793
|
+
* console.log(bridges.length); // 2;
|
|
668
794
|
*/
|
|
669
795
|
getBridges() {
|
|
670
796
|
return this.tarjan().bridges;
|
|
@@ -674,6 +800,25 @@ export class UndirectedGraph<
|
|
|
674
800
|
* Get articulation points discovered by `tarjan()`.
|
|
675
801
|
* @returns Array of cut vertices.
|
|
676
802
|
* @remarks Time O(C), Space O(1)
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
* @example
|
|
812
|
+
* // Find articulation points
|
|
813
|
+
* const g = new UndirectedGraph();
|
|
814
|
+
* g.addVertex('A');
|
|
815
|
+
* g.addVertex('B');
|
|
816
|
+
* g.addVertex('C');
|
|
817
|
+
* g.addEdge('A', 'B');
|
|
818
|
+
* g.addEdge('B', 'C');
|
|
819
|
+
* const cuts = g.getCutVertices();
|
|
820
|
+
* console.log(cuts.length); // 1;
|
|
821
|
+
* console.log(cuts[0].key); // 'B';
|
|
677
822
|
*/
|
|
678
823
|
getCutVertices() {
|
|
679
824
|
return this.tarjan().cutVertices;
|
|
@@ -29,83 +29,6 @@ import { ERR } from '../../common';
|
|
|
29
29
|
* If you try to insert another entry with the same key, the new one will replace the old entry.
|
|
30
30
|
* 4. Unordered Collection: HashMap does not guarantee the order of entries, and the order may change over time.
|
|
31
31
|
* @example
|
|
32
|
-
* // should maintain insertion order
|
|
33
|
-
* const linkedHashMap = new LinkedHashMap<number, string>();
|
|
34
|
-
* linkedHashMap.set(1, 'A');
|
|
35
|
-
* linkedHashMap.set(2, 'B');
|
|
36
|
-
* linkedHashMap.set(3, 'C');
|
|
37
|
-
*
|
|
38
|
-
* const result = Array.from(linkedHashMap);
|
|
39
|
-
* console.log(result); // [
|
|
40
|
-
* // [1, 'A'],
|
|
41
|
-
* // [2, 'B'],
|
|
42
|
-
* // [3, 'C']
|
|
43
|
-
* // ];
|
|
44
|
-
* @example
|
|
45
|
-
* // basic HashMap creation and set operation
|
|
46
|
-
* // Create a simple HashMap with key-value pairs
|
|
47
|
-
* const map = new HashMap<number, string>([
|
|
48
|
-
* [1, 'one'],
|
|
49
|
-
* [2, 'two'],
|
|
50
|
-
* [3, 'three']
|
|
51
|
-
* ]);
|
|
52
|
-
*
|
|
53
|
-
* // Verify size
|
|
54
|
-
* console.log(map.size); // 3;
|
|
55
|
-
*
|
|
56
|
-
* // Set a new key-value pair
|
|
57
|
-
* map.set(4, 'four');
|
|
58
|
-
* console.log(map.size); // 4;
|
|
59
|
-
*
|
|
60
|
-
* // Verify entries
|
|
61
|
-
* console.log([...map.entries()]); // length: 4;
|
|
62
|
-
* @example
|
|
63
|
-
* // HashMap get and has operations
|
|
64
|
-
* const map = new HashMap<string, number>([
|
|
65
|
-
* ['apple', 1],
|
|
66
|
-
* ['banana', 2],
|
|
67
|
-
* ['cherry', 3]
|
|
68
|
-
* ]);
|
|
69
|
-
*
|
|
70
|
-
* // Check if key exists
|
|
71
|
-
* console.log(map.has('apple')); // true;
|
|
72
|
-
* console.log(map.has('date')); // false;
|
|
73
|
-
*
|
|
74
|
-
* // Get value by key
|
|
75
|
-
* console.log(map.get('banana')); // 2;
|
|
76
|
-
* console.log(map.get('grape')); // undefined;
|
|
77
|
-
*
|
|
78
|
-
* // Get all keys and values
|
|
79
|
-
* const keys = [...map.keys()];
|
|
80
|
-
* const values = [...map.values()];
|
|
81
|
-
* console.log(keys); // contains 'apple';
|
|
82
|
-
* console.log(values); // contains 3;
|
|
83
|
-
* @example
|
|
84
|
-
* // HashMap iteration and filter operations
|
|
85
|
-
* const map = new HashMap<number, string>([
|
|
86
|
-
* [1, 'Alice'],
|
|
87
|
-
* [2, 'Bob'],
|
|
88
|
-
* [3, 'Charlie'],
|
|
89
|
-
* [4, 'Diana'],
|
|
90
|
-
* [5, 'Eve']
|
|
91
|
-
* ]);
|
|
92
|
-
*
|
|
93
|
-
* // Iterate through entries
|
|
94
|
-
* const entries: [number, string][] = [];
|
|
95
|
-
* for (const [key, value] of map) {
|
|
96
|
-
* entries.push([key, value]);
|
|
97
|
-
* }
|
|
98
|
-
* console.log(entries); // length: 5;
|
|
99
|
-
*
|
|
100
|
-
* // Filter operation (for iteration with collection methods)
|
|
101
|
-
* const filtered = [...map].filter(([key]) => key > 2);
|
|
102
|
-
* console.log(filtered.length); // 3;
|
|
103
|
-
*
|
|
104
|
-
* // Map operation
|
|
105
|
-
* const values = [...map.values()].map(v => v.length);
|
|
106
|
-
* console.log(values); // contains 3; // 'Bob', 'Eve'
|
|
107
|
-
* console.log(values); // contains 7;
|
|
108
|
-
* @example
|
|
109
32
|
* // HashMap for user session caching O(1) performance
|
|
110
33
|
* interface UserSession {
|
|
111
34
|
* userId: number;
|
|
@@ -157,6 +80,19 @@ import { ERR } from '../../common';
|
|
|
157
80
|
* // Get all active sessions
|
|
158
81
|
* const activeCount = [...sessionCache.values()].length;
|
|
159
82
|
* console.log(activeCount); // 2;
|
|
83
|
+
* @example
|
|
84
|
+
* // Aggregate values
|
|
85
|
+
* const counts = new HashMap<string, number>([['a', 5], ['b', 3], ['c', 8]]);
|
|
86
|
+
*
|
|
87
|
+
* const total = counts.reduce((sum, v) => sum + (v ?? 0), 0);
|
|
88
|
+
* console.log(total); // 16;
|
|
89
|
+
* @example
|
|
90
|
+
* // Iterate over entries
|
|
91
|
+
* const map = new HashMap<string, number>([['x', 1], ['y', 2]]);
|
|
92
|
+
* const keys: string[] = [];
|
|
93
|
+
*
|
|
94
|
+
* map.forEach((v, k) => keys.push(k));
|
|
95
|
+
* console.log(keys.sort()); // ['x', 'y'];
|
|
160
96
|
*/
|
|
161
97
|
export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {
|
|
162
98
|
/**
|
|
@@ -235,6 +171,19 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
235
171
|
* Check whether the map is empty.
|
|
236
172
|
* @remarks Time O(1), Space O(1)
|
|
237
173
|
* @returns True if size is 0.
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
* @example
|
|
184
|
+
* // Check if empty
|
|
185
|
+
* const map = new HashMap();
|
|
186
|
+
* console.log(map.isEmpty()); // true;
|
|
238
187
|
*/
|
|
239
188
|
isEmpty(): boolean {
|
|
240
189
|
return this._size === 0;
|
|
@@ -244,6 +193,20 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
244
193
|
* Remove all entries and reset counters.
|
|
245
194
|
* @remarks Time O(N), Space O(1)
|
|
246
195
|
* @returns void
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
* @example
|
|
206
|
+
* // Remove all entries
|
|
207
|
+
* const map = new HashMap<string, number>([['a', 1], ['b', 2]]);
|
|
208
|
+
* map.clear();
|
|
209
|
+
* console.log(map.isEmpty()); // true;
|
|
247
210
|
*/
|
|
248
211
|
clear(): void {
|
|
249
212
|
this._store = {};
|
|
@@ -266,6 +229,46 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
266
229
|
* @param key - Key.
|
|
267
230
|
* @param value - Value.
|
|
268
231
|
* @returns True when the operation succeeds.
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
* @example
|
|
255
|
+
* // basic HashMap creation and set operation
|
|
256
|
+
* // Create a simple HashMap with key-value pairs
|
|
257
|
+
* const map = new HashMap<number, string>([
|
|
258
|
+
* [1, 'one'],
|
|
259
|
+
* [2, 'two'],
|
|
260
|
+
* [3, 'three']
|
|
261
|
+
* ]);
|
|
262
|
+
*
|
|
263
|
+
* // Verify size
|
|
264
|
+
* console.log(map.size); // 3;
|
|
265
|
+
*
|
|
266
|
+
* // Set a new key-value pair
|
|
267
|
+
* map.set(4, 'four');
|
|
268
|
+
* console.log(map.size); // 4;
|
|
269
|
+
*
|
|
270
|
+
* // Verify entries
|
|
271
|
+
* console.log([...map.entries()]); // length: 4;
|
|
269
272
|
*/
|
|
270
273
|
set(key: K, value: V): boolean {
|
|
271
274
|
if (this._isObjKey(key)) {
|
|
@@ -284,6 +287,20 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
284
287
|
* @remarks Time O(N), Space O(N)
|
|
285
288
|
* @param entryOrRawElements - Iterable of entries or raw elements to insert.
|
|
286
289
|
* @returns Array of per-entry results.
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
* @example
|
|
300
|
+
* // Add multiple entries
|
|
301
|
+
* const map = new HashMap<string, number>();
|
|
302
|
+
* map.setMany([['a', 1], ['b', 2], ['c', 3]]);
|
|
303
|
+
* console.log(map.size); // 3;
|
|
287
304
|
*/
|
|
288
305
|
setMany(entryOrRawElements: Iterable<R | [K, V]>): boolean[] {
|
|
289
306
|
const results: boolean[] = [];
|
|
@@ -301,6 +318,38 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
301
318
|
* @remarks Time O(1), Space O(1)
|
|
302
319
|
* @param key - Key to look up.
|
|
303
320
|
* @returns Value or undefined.
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
* @example
|
|
333
|
+
* // HashMap get and has operations
|
|
334
|
+
* const map = new HashMap<string, number>([
|
|
335
|
+
* ['apple', 1],
|
|
336
|
+
* ['banana', 2],
|
|
337
|
+
* ['cherry', 3]
|
|
338
|
+
* ]);
|
|
339
|
+
*
|
|
340
|
+
* // Check if key exists
|
|
341
|
+
* console.log(map.has('apple')); // true;
|
|
342
|
+
* console.log(map.has('date')); // false;
|
|
343
|
+
*
|
|
344
|
+
* // Get value by key
|
|
345
|
+
* console.log(map.get('banana')); // 2;
|
|
346
|
+
* console.log(map.get('grape')); // undefined;
|
|
347
|
+
*
|
|
348
|
+
* // Get all keys and values
|
|
349
|
+
* const keys = [...map.keys()];
|
|
350
|
+
* const values = [...map.values()];
|
|
351
|
+
* console.log(keys); // contains 'apple';
|
|
352
|
+
* console.log(values); // contains 3;
|
|
304
353
|
*/
|
|
305
354
|
override get(key: K): V | undefined {
|
|
306
355
|
if (this._isObjKey(key)) return this.objMap.get(key);
|
|
@@ -313,6 +362,23 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
313
362
|
* @remarks Time O(1), Space O(1)
|
|
314
363
|
* @param key - Key to test.
|
|
315
364
|
* @returns True if present.
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
* @example
|
|
377
|
+
* // Check key existence
|
|
378
|
+
* const map = new HashMap<string, number>([['a', 1], ['b', 2]]);
|
|
379
|
+
*
|
|
380
|
+
* console.log(map.has('a')); // true;
|
|
381
|
+
* console.log(map.has('z')); // false;
|
|
316
382
|
*/
|
|
317
383
|
override has(key: K): boolean {
|
|
318
384
|
if (this._isObjKey(key)) return this.objMap.has(key);
|
|
@@ -325,6 +391,24 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
325
391
|
* @remarks Time O(1), Space O(1)
|
|
326
392
|
* @param key - Key to delete.
|
|
327
393
|
* @returns True if the key was found and removed.
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
* @example
|
|
406
|
+
* // Remove entries by key
|
|
407
|
+
* const map = new HashMap<string, number>([['x', 10], ['y', 20], ['z', 30]]);
|
|
408
|
+
*
|
|
409
|
+
* console.log(map.delete('y')); // true;
|
|
410
|
+
* console.log(map.has('y')); // false;
|
|
411
|
+
* console.log(map.size); // 2;
|
|
328
412
|
*/
|
|
329
413
|
delete(key: K): boolean {
|
|
330
414
|
if (this._isObjKey(key)) {
|
|
@@ -357,6 +441,21 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
357
441
|
* Deep clone this map, preserving hashing behavior.
|
|
358
442
|
* @remarks Time O(N), Space O(N)
|
|
359
443
|
* @returns A new map with the same content.
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
* @example
|
|
454
|
+
* // Create independent copy
|
|
455
|
+
* const map = new HashMap<string, number>([['a', 1]]);
|
|
456
|
+
* const copy = map.clone();
|
|
457
|
+
* copy.set('a', 99);
|
|
458
|
+
* console.log(map.get('a')); // 1;
|
|
360
459
|
*/
|
|
361
460
|
clone(): this {
|
|
362
461
|
const opts = { hashFn: this._hashFn, toEntryFn: this._toEntryFn };
|
|
@@ -370,6 +469,24 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
370
469
|
* @param callbackfn - Mapping function (key, value, index, map) → newValue.
|
|
371
470
|
* @param [thisArg] - Value for `this` inside the callback.
|
|
372
471
|
* @returns A new map with transformed values.
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
* @example
|
|
484
|
+
* // Transform all values
|
|
485
|
+
* const prices = new HashMap<string, number>([['apple', 1], ['banana', 2]]);
|
|
486
|
+
*
|
|
487
|
+
* const doubled = prices.map(v => (v ?? 0) * 2);
|
|
488
|
+
* console.log(doubled.get('apple')); // 2;
|
|
489
|
+
* console.log(doubled.get('banana')); // 4;
|
|
373
490
|
*/
|
|
374
491
|
map<VM>(callbackfn: EntryCallback<K, V, VM>, thisArg?: any): any {
|
|
375
492
|
const out = this._createLike<K, VM, [K, VM]>();
|
|
@@ -384,6 +501,42 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
384
501
|
* @param predicate - Predicate (key, value, index, map) → boolean.
|
|
385
502
|
* @param [thisArg] - Value for `this` inside the predicate.
|
|
386
503
|
* @returns A new map containing entries that satisfied the predicate.
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
* @example
|
|
516
|
+
* // HashMap iteration and filter operations
|
|
517
|
+
* const map = new HashMap<number, string>([
|
|
518
|
+
* [1, 'Alice'],
|
|
519
|
+
* [2, 'Bob'],
|
|
520
|
+
* [3, 'Charlie'],
|
|
521
|
+
* [4, 'Diana'],
|
|
522
|
+
* [5, 'Eve']
|
|
523
|
+
* ]);
|
|
524
|
+
*
|
|
525
|
+
* // Iterate through entries
|
|
526
|
+
* const entries: [number, string][] = [];
|
|
527
|
+
* for (const [key, value] of map) {
|
|
528
|
+
* entries.push([key, value]);
|
|
529
|
+
* }
|
|
530
|
+
* console.log(entries); // length: 5;
|
|
531
|
+
*
|
|
532
|
+
* // Filter operation (for iteration with collection methods)
|
|
533
|
+
* const filtered = [...map].filter(([key]) => key > 2);
|
|
534
|
+
* console.log(filtered.length); // 3;
|
|
535
|
+
*
|
|
536
|
+
* // Map operation
|
|
537
|
+
* const values = [...map.values()].map(v => v.length);
|
|
538
|
+
* console.log(values); // contains 3; // 'Bob', 'Eve'
|
|
539
|
+
* console.log(values); // contains 7;
|
|
387
540
|
*/
|
|
388
541
|
|
|
389
542
|
filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): any {
|