data-structure-typed 2.4.4 → 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.
Files changed (80) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/README.md +34 -1
  3. package/dist/cjs/index.cjs +10639 -2151
  4. package/dist/cjs-legacy/index.cjs +10694 -2195
  5. package/dist/esm/index.mjs +10639 -2150
  6. package/dist/esm-legacy/index.mjs +10694 -2194
  7. package/dist/types/common/error.d.ts +23 -0
  8. package/dist/types/common/index.d.ts +1 -0
  9. package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
  10. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
  11. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
  12. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
  13. package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
  14. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
  15. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
  16. package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
  17. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
  18. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
  19. package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
  20. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  21. package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
  22. package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
  23. package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
  24. package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
  25. package/dist/types/data-structures/heap/heap.d.ts +287 -99
  26. package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
  27. package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
  28. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
  29. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
  30. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
  31. package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
  32. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
  33. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
  34. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
  35. package/dist/types/data-structures/queue/deque.d.ts +313 -66
  36. package/dist/types/data-structures/queue/queue.d.ts +211 -42
  37. package/dist/types/data-structures/stack/stack.d.ts +174 -32
  38. package/dist/types/data-structures/trie/trie.d.ts +213 -43
  39. package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
  40. package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
  41. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  42. package/dist/umd/data-structure-typed.js +10725 -2221
  43. package/dist/umd/data-structure-typed.min.js +4 -2
  44. package/package.json +5 -4
  45. package/src/common/error.ts +60 -0
  46. package/src/common/index.ts +2 -0
  47. package/src/data-structures/base/iterable-element-base.ts +2 -2
  48. package/src/data-structures/binary-tree/avl-tree.ts +146 -51
  49. package/src/data-structures/binary-tree/binary-indexed-tree.ts +317 -247
  50. package/src/data-structures/binary-tree/binary-tree.ts +567 -121
  51. package/src/data-structures/binary-tree/bst.ts +370 -37
  52. package/src/data-structures/binary-tree/red-black-tree.ts +328 -96
  53. package/src/data-structures/binary-tree/segment-tree.ts +378 -248
  54. package/src/data-structures/binary-tree/tree-map.ts +1411 -13
  55. package/src/data-structures/binary-tree/tree-multi-map.ts +1218 -215
  56. package/src/data-structures/binary-tree/tree-multi-set.ts +959 -69
  57. package/src/data-structures/binary-tree/tree-set.ts +1257 -15
  58. package/src/data-structures/graph/abstract-graph.ts +106 -1
  59. package/src/data-structures/graph/directed-graph.ts +233 -47
  60. package/src/data-structures/graph/map-graph.ts +59 -1
  61. package/src/data-structures/graph/undirected-graph.ts +308 -59
  62. package/src/data-structures/hash/hash-map.ts +254 -79
  63. package/src/data-structures/heap/heap.ts +305 -102
  64. package/src/data-structures/heap/max-heap.ts +48 -3
  65. package/src/data-structures/heap/min-heap.ts +59 -0
  66. package/src/data-structures/linked-list/doubly-linked-list.ts +303 -44
  67. package/src/data-structures/linked-list/singly-linked-list.ts +293 -65
  68. package/src/data-structures/linked-list/skip-linked-list.ts +707 -90
  69. package/src/data-structures/matrix/matrix.ts +433 -22
  70. package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
  71. package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
  72. package/src/data-structures/priority-queue/priority-queue.ts +60 -0
  73. package/src/data-structures/queue/deque.ts +358 -68
  74. package/src/data-structures/queue/queue.ts +223 -42
  75. package/src/data-structures/stack/stack.ts +184 -32
  76. package/src/data-structures/trie/trie.ts +227 -44
  77. package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
  78. package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
  79. package/src/types/data-structures/queue/deque.ts +7 -0
  80. package/src/utils/utils.ts +4 -2
@@ -10,12 +10,18 @@
10
10
  import type { Comparator } from '../../types';
11
11
  import type { TreeMapEntryCallback, TreeMapOptions, TreeMapRangeOptions, TreeMapReduceCallback } from '../../types';
12
12
  import { RedBlackTree } from './red-black-tree';
13
+ import { ERR } from '../../common';
13
14
 
14
15
  /**
15
16
  * An ordered Map backed by a red-black tree.
16
17
  *
17
18
  * - Iteration order is ascending by key.
18
19
  * - No node exposure: all APIs use keys/values only.
20
+ * @example
21
+ * // Set multiple key-value pairs
22
+ * const tm = new TreeMap<number, string>();
23
+ * tm.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
24
+ * console.log(tm.size); // 3;
19
25
  */
20
26
  export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | undefined]> {
21
27
  readonly #core: RedBlackTree<K, V>;
@@ -58,7 +64,7 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
58
64
  } else {
59
65
  // Validate entries like native Map: each item must be a 2-tuple-like value.
60
66
  if (!Array.isArray(item) || item.length < 2) {
61
- throw new TypeError('TreeMap: each entry must be a [key, value] tuple');
67
+ throw new TypeError(ERR.invalidEntry('TreeMap'));
62
68
  }
63
69
  k = item[0] as K;
64
70
  v = item[1] as V | undefined;
@@ -81,7 +87,8 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
81
87
  static createDefaultComparator<K>(): Comparator<K> {
82
88
  return (a: K, b: K): number => {
83
89
  if (typeof a === 'number' && typeof b === 'number') {
84
- if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError('TreeMap: NaN is not a valid key');
90
+ /* istanbul ignore next -- _validateKey prevents NaN from entering the tree */
91
+ if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN('TreeMap'));
85
92
  const aa = Object.is(a, -0) ? 0 : a;
86
93
  const bb = Object.is(b, -0) ? 0 : b;
87
94
  return aa > bb ? 1 : aa < bb ? -1 : 0;
@@ -94,11 +101,12 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
94
101
  if (a instanceof Date && b instanceof Date) {
95
102
  const ta = a.getTime();
96
103
  const tb = b.getTime();
97
- if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError('TreeMap: invalid Date key');
104
+ /* istanbul ignore next -- _validateKey prevents invalid Date from entering the tree */
105
+ if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate('TreeMap'));
98
106
  return ta > tb ? 1 : ta < tb ? -1 : 0;
99
107
  }
100
108
 
101
- throw new TypeError('TreeMap: comparator is required for non-number/non-string/non-Date keys');
109
+ throw new TypeError(ERR.comparatorRequired('TreeMap'));
102
110
  };
103
111
  }
104
112
 
@@ -106,18 +114,18 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
106
114
  if (!this.#isDefaultComparator) return;
107
115
 
108
116
  if (typeof key === 'number') {
109
- if (Number.isNaN(key)) throw new TypeError('TreeMap: NaN is not a valid key');
117
+ if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN('TreeMap'));
110
118
  return;
111
119
  }
112
120
 
113
121
  if (typeof key === 'string') return;
114
122
 
115
123
  if (key instanceof Date) {
116
- if (Number.isNaN(key.getTime())) throw new TypeError('TreeMap: invalid Date key');
124
+ if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate('TreeMap'));
117
125
  return;
118
126
  }
119
127
 
120
- throw new TypeError('TreeMap: comparator is required for non-number/non-string/non-Date keys');
128
+ throw new TypeError(ERR.comparatorRequired('TreeMap'));
121
129
  }
122
130
 
123
131
  /**
@@ -129,6 +137,52 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
129
137
 
130
138
  /**
131
139
  * Whether the map is empty.
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+
166
+
167
+
168
+
169
+
170
+
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+
181
+
182
+
183
+ * @example
184
+ * // Check empty
185
+ * console.log(new TreeMap().isEmpty()); // true;
132
186
  */
133
187
  isEmpty(): boolean {
134
188
  return this.size === 0;
@@ -137,6 +191,78 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
137
191
  /**
138
192
  * Set or overwrite a value for a key.
139
193
  * @remarks Expected time O(log n)
194
+
195
+
196
+
197
+
198
+
199
+
200
+
201
+
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+
232
+
233
+
234
+
235
+
236
+
237
+
238
+
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+ * @example
247
+ * // Sorted dictionary for a contact book
248
+ * const contacts = new TreeMap<string, string>([
249
+ * ['Bob', '555-0102'],
250
+ * ['Alice', '555-0101'],
251
+ * ['Charlie', '555-0103']
252
+ * ]);
253
+ *
254
+ * // Contacts are automatically sorted by name
255
+ * console.log([...contacts.keys()]); // ['Alice', 'Bob', 'Charlie'];
256
+ * console.log(contacts.get('Bob')); // '555-0102';
257
+ *
258
+ * // Find the first contact alphabetically after 'B'
259
+ * console.log(contacts.ceiling('B')); // ['Bob', '555-0102'];
260
+ *
261
+ * // Find contacts in range
262
+ * console.log(contacts.rangeSearch(['Alice', 'Bob'])); // [
263
+ * // ['Alice', '555-0101'],
264
+ * // ['Bob', '555-0102']
265
+ * // ];
140
266
  */
141
267
  set(key: K, value: V | undefined): this {
142
268
  this._validateKey(key);
@@ -147,6 +273,71 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
147
273
  /**
148
274
  * Get the value under a key.
149
275
  * @remarks Expected time O(log n)
276
+
277
+
278
+
279
+
280
+
281
+
282
+
283
+
284
+
285
+
286
+
287
+
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
+ * @example
331
+ * // Configuration registry with typed lookups
332
+ * const config = new TreeMap<string, number>([
333
+ * ['maxRetries', 3],
334
+ * ['timeout', 5000],
335
+ * ['poolSize', 10]
336
+ * ]);
337
+ *
338
+ * console.log(config.get('timeout')); // 5000;
339
+ * console.log(config.get('missing')); // undefined;
340
+ * console.log(config.size); // 3;
150
341
  */
151
342
  get(key: K): V | undefined {
152
343
  this._validateKey(key);
@@ -156,6 +347,70 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
156
347
  /**
157
348
  * Test whether a key exists.
158
349
  * @remarks Expected time O(log n)
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
+
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+
387
+
388
+
389
+
390
+
391
+
392
+
393
+
394
+
395
+
396
+
397
+
398
+
399
+
400
+
401
+
402
+
403
+
404
+ * @example
405
+ * // Feature flag checking
406
+ * const flags = new TreeMap<string, boolean>([
407
+ * ['darkMode', true],
408
+ * ['betaFeature', false],
409
+ * ['notifications', true]
410
+ * ]);
411
+ *
412
+ * console.log(flags.has('darkMode')); // true;
413
+ * console.log(flags.has('unknownFlag')); // false;
159
414
  */
160
415
  has(key: K): boolean {
161
416
  this._validateKey(key);
@@ -166,6 +421,72 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
166
421
  * Delete a key.
167
422
  * @returns `true` if the key existed; otherwise `false`.
168
423
  * @remarks Expected time O(log n)
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
+
455
+
456
+
457
+
458
+
459
+
460
+
461
+
462
+
463
+
464
+
465
+
466
+
467
+
468
+
469
+
470
+
471
+
472
+
473
+
474
+
475
+
476
+
477
+
478
+ * @example
479
+ * // Session management with expiry
480
+ * const sessions = new TreeMap<string, number>([
481
+ * ['sess_abc', Date.now()],
482
+ * ['sess_def', Date.now()],
483
+ * ['sess_ghi', Date.now()]
484
+ * ]);
485
+ *
486
+ * console.log(sessions.size); // 3;
487
+ * sessions.delete('sess_def');
488
+ * console.log(sessions.has('sess_def')); // false;
489
+ * console.log(sessions.size); // 2;
169
490
  */
170
491
  delete(key: K): boolean {
171
492
  this._validateKey(key);
@@ -175,6 +496,54 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
175
496
 
176
497
  /**
177
498
  * Remove all entries.
499
+
500
+
501
+
502
+
503
+
504
+
505
+
506
+
507
+
508
+
509
+
510
+
511
+
512
+
513
+
514
+
515
+
516
+
517
+
518
+
519
+
520
+
521
+
522
+
523
+
524
+
525
+
526
+
527
+
528
+
529
+
530
+
531
+
532
+
533
+
534
+
535
+
536
+
537
+
538
+
539
+
540
+
541
+
542
+ * @example
543
+ * // Remove all
544
+ * const tm = new TreeMap<number, string>([[1, 'a']]);
545
+ * tm.clear();
546
+ * console.log(tm.isEmpty()); // true;
178
547
  */
179
548
  clear(): void {
180
549
  this.#core.clear();
@@ -182,6 +551,53 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
182
551
 
183
552
  /**
184
553
  * Iterate over keys in ascending order.
554
+
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
+ * // Get sorted keys
599
+ * const tm = new TreeMap<number, string>([[3, 'c'], [1, 'a']]);
600
+ * console.log([...tm.keys()]); // [1, 3];
185
601
  */
186
602
  keys(): IterableIterator<K> {
187
603
  return this.#core.keys();
@@ -197,6 +613,53 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
197
613
  * Iterate over values in ascending key order.
198
614
  *
199
615
  * Note: values may be `undefined` (TreeMap allows storing `undefined`, like native `Map`).
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
+
658
+
659
+ * @example
660
+ * // Get values in key order
661
+ * const tm = new TreeMap<number, string>([[2, 'b'], [1, 'a']]);
662
+ * console.log([...tm.values()]); // ['a', 'b'];
200
663
  */
201
664
  *values(): IterableIterator<V | undefined> {
202
665
  for (const k of this.keys()) yield this._entryFromKey(k)[1];
@@ -206,6 +669,53 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
206
669
  * Iterate over `[key, value]` entries in ascending key order.
207
670
  *
208
671
  * Note: values may be `undefined`.
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
+
710
+
711
+
712
+
713
+
714
+
715
+ * @example
716
+ * // Iterate key-value pairs
717
+ * const tm = new TreeMap<number, string>([[3, 'c'], [1, 'a'], [2, 'b']]);
718
+ * console.log([...tm.entries()]); // [[1, 'a'], [2, 'b'], [3, 'c']];
209
719
  */
210
720
  *entries(): IterableIterator<[K, V | undefined]> {
211
721
  for (const k of this.keys()) yield this._entryFromKey(k);
@@ -219,6 +729,55 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
219
729
  * Visit each entry in ascending key order.
220
730
  *
221
731
  * Note: callback value may be `undefined`.
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
+
768
+
769
+
770
+
771
+
772
+
773
+
774
+
775
+ * @example
776
+ * // Execute for each entry
777
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
778
+ * const pairs: string[] = [];
779
+ * tm.forEach((v, k) => pairs.push(`${k}:${v}`));
780
+ * console.log(pairs); // ['1:a', '2:b'];
222
781
  */
223
782
  forEach(cb: (value: V | undefined, key: K, map: TreeMap<K, V>) => void, thisArg?: any): void {
224
783
  for (const [k, v] of this) cb.call(thisArg, v, k, this);
@@ -229,6 +788,54 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
229
788
  *
230
789
  * This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
231
790
  * @remarks Time O(n log n) expected, Space O(n)
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
+
828
+
829
+
830
+
831
+
832
+
833
+
834
+ * @example
835
+ * // Transform entries
836
+ * const tm = new TreeMap<number, number>([[1, 10], [2, 20]]);
837
+ * const doubled = tm.map((v, k) => [k, (v ?? 0) * 2] as [number, number]);
838
+ * console.log([...doubled.values()]); // [20, 40];
232
839
  */
233
840
  map<MK, MV>(
234
841
  callbackfn: TreeMapEntryCallback<K, V, [MK, MV], TreeMap<K, V>>,
@@ -249,6 +856,54 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
249
856
  /**
250
857
  * Create a new TreeMap containing only entries that satisfy the predicate.
251
858
  * @remarks Time O(n log n) expected, Space O(n)
859
+
860
+
861
+
862
+
863
+
864
+
865
+
866
+
867
+
868
+
869
+
870
+
871
+
872
+
873
+
874
+
875
+
876
+
877
+
878
+
879
+
880
+
881
+
882
+
883
+
884
+
885
+
886
+
887
+
888
+
889
+
890
+
891
+
892
+
893
+
894
+
895
+
896
+
897
+
898
+
899
+
900
+
901
+
902
+ * @example
903
+ * // Filter entries
904
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b'], [3, 'c']]);
905
+ * const filtered = tm.filter((v, k) => k > 1);
906
+ * console.log([...filtered.keys()]); // [2, 3];
252
907
  */
253
908
  filter(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): TreeMap<K, V> {
254
909
  const out = new TreeMap<K, V>([], { comparator: this.#userComparator });
@@ -265,6 +920,53 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
265
920
  /**
266
921
  * Reduce entries into a single accumulator.
267
922
  * @remarks Time O(n), Space O(1)
923
+
924
+
925
+
926
+
927
+
928
+
929
+
930
+
931
+
932
+
933
+
934
+
935
+
936
+
937
+
938
+
939
+
940
+
941
+
942
+
943
+
944
+
945
+
946
+
947
+
948
+
949
+
950
+
951
+
952
+
953
+
954
+
955
+
956
+
957
+
958
+
959
+
960
+
961
+
962
+
963
+
964
+
965
+
966
+ * @example
967
+ * // Aggregate values
968
+ * const tm = new TreeMap<number, number>([[1, 10], [2, 20]]);
969
+ * console.log(tm.reduce((acc, v) => acc + (v ?? 0), 0)); // 30;
268
970
  */
269
971
  reduce<A>(callbackfn: TreeMapReduceCallback<K, V, A, TreeMap<K, V>>, initialValue: A): A {
270
972
  let acc = initialValue;
@@ -276,6 +978,51 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
276
978
  /**
277
979
  * Test whether all entries satisfy a predicate.
278
980
  * @remarks Time O(n), Space O(1)
981
+
982
+
983
+
984
+
985
+
986
+
987
+
988
+
989
+
990
+
991
+
992
+
993
+
994
+
995
+
996
+
997
+
998
+
999
+
1000
+
1001
+
1002
+
1003
+
1004
+
1005
+
1006
+
1007
+
1008
+
1009
+
1010
+
1011
+
1012
+
1013
+
1014
+
1015
+
1016
+
1017
+
1018
+
1019
+
1020
+
1021
+
1022
+ * @example
1023
+ * // Test all entries
1024
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
1025
+ * console.log(tm.every((v, k) => k > 0)); // true;
279
1026
  */
280
1027
  every(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): boolean {
281
1028
  let index = 0;
@@ -291,6 +1038,51 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
291
1038
  /**
292
1039
  * Test whether any entry satisfies a predicate.
293
1040
  * @remarks Time O(n), Space O(1)
1041
+
1042
+
1043
+
1044
+
1045
+
1046
+
1047
+
1048
+
1049
+
1050
+
1051
+
1052
+
1053
+
1054
+
1055
+
1056
+
1057
+
1058
+
1059
+
1060
+
1061
+
1062
+
1063
+
1064
+
1065
+
1066
+
1067
+
1068
+
1069
+
1070
+
1071
+
1072
+
1073
+
1074
+
1075
+
1076
+
1077
+
1078
+
1079
+
1080
+
1081
+
1082
+ * @example
1083
+ * // Test any entry
1084
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
1085
+ * console.log(tm.some((v, k) => k === 2)); // true;
294
1086
  */
295
1087
  some(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): boolean {
296
1088
  let index = 0;
@@ -307,6 +1099,51 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
307
1099
  * Find the first entry that satisfies a predicate.
308
1100
  * @returns The first matching `[key, value]` tuple, or `undefined`.
309
1101
  * @remarks Time O(n), Space O(1)
1102
+
1103
+
1104
+
1105
+
1106
+
1107
+
1108
+
1109
+
1110
+
1111
+
1112
+
1113
+
1114
+
1115
+
1116
+
1117
+
1118
+
1119
+
1120
+
1121
+
1122
+
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+
1129
+
1130
+
1131
+
1132
+
1133
+
1134
+
1135
+
1136
+
1137
+
1138
+
1139
+
1140
+
1141
+
1142
+
1143
+ * @example
1144
+ * // Find matching entry
1145
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
1146
+ * console.log(tm.find(v => v === 'b')?.[0]); // 2;
310
1147
  */
311
1148
  find(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): [K, V | undefined] | undefined {
312
1149
  let index = 0;
@@ -322,6 +1159,53 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
322
1159
  /**
323
1160
  * Materialize the map into an array of `[key, value]` tuples.
324
1161
  * @remarks Time O(n), Space O(n)
1162
+
1163
+
1164
+
1165
+
1166
+
1167
+
1168
+
1169
+
1170
+
1171
+
1172
+
1173
+
1174
+
1175
+
1176
+
1177
+
1178
+
1179
+
1180
+
1181
+
1182
+
1183
+
1184
+
1185
+
1186
+
1187
+
1188
+
1189
+
1190
+
1191
+
1192
+
1193
+
1194
+
1195
+
1196
+
1197
+
1198
+
1199
+
1200
+
1201
+
1202
+
1203
+
1204
+
1205
+ * @example
1206
+ * // Convert to array
1207
+ * const tm = new TreeMap<number, string>([[2, 'b'], [1, 'a']]);
1208
+ * console.log(tm.toArray()); // [[1, 'a'], [2, 'b']];
325
1209
  */
326
1210
  toArray(): Array<[K, V | undefined]> {
327
1211
  return [...this];
@@ -330,6 +1214,53 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
330
1214
  /**
331
1215
  * Print a human-friendly representation.
332
1216
  * @remarks Time O(n), Space O(n)
1217
+
1218
+
1219
+
1220
+
1221
+
1222
+
1223
+
1224
+
1225
+
1226
+
1227
+
1228
+
1229
+
1230
+
1231
+
1232
+
1233
+
1234
+
1235
+
1236
+
1237
+
1238
+
1239
+
1240
+
1241
+
1242
+
1243
+
1244
+
1245
+
1246
+
1247
+
1248
+
1249
+
1250
+
1251
+
1252
+
1253
+
1254
+
1255
+
1256
+
1257
+
1258
+
1259
+
1260
+ * @example
1261
+ * // Display tree
1262
+ * const tm = new TreeMap<number, string>([[1, 'a']]);
1263
+ * expect(() => tm.print()).not.toThrow();
333
1264
  */
334
1265
  print(): void {
335
1266
  // Delegate to the underlying tree's visualization.
@@ -341,6 +1272,44 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
341
1272
 
342
1273
  /**
343
1274
  * Smallest entry by key.
1275
+
1276
+
1277
+
1278
+
1279
+
1280
+
1281
+
1282
+
1283
+
1284
+
1285
+
1286
+
1287
+ * @example
1288
+ * // Leaderboard with ranked scores
1289
+ * // Use score as key (descending), player name as value
1290
+ * const leaderboard = new TreeMap<number, string>([], {
1291
+ * comparator: (a, b) => b - a // descending
1292
+ * });
1293
+ *
1294
+ * leaderboard.set(1500, 'Alice');
1295
+ * leaderboard.set(2200, 'Bob');
1296
+ * leaderboard.set(1800, 'Charlie');
1297
+ * leaderboard.set(2500, 'Diana');
1298
+ *
1299
+ * // Top 3 players (first 3 in descending order)
1300
+ * const top3 = [...leaderboard.entries()].slice(0, 3);
1301
+ * console.log(top3); // [
1302
+ * // [2500, 'Diana'],
1303
+ * // [2200, 'Bob'],
1304
+ * // [1800, 'Charlie']
1305
+ * // ];
1306
+ *
1307
+ * // Highest scorer
1308
+ * console.log(leaderboard.first()); // [2500, 'Diana'];
1309
+ *
1310
+ * // Remove lowest scorer
1311
+ * console.log(leaderboard.pollLast()); // [1500, 'Alice'];
1312
+ * console.log(leaderboard.size); // 3;
344
1313
  */
345
1314
  first(): [K, V | undefined] | undefined {
346
1315
  const k = this.#core.getLeftMost();
@@ -349,6 +1318,28 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
349
1318
 
350
1319
  /**
351
1320
  * Largest entry by key.
1321
+
1322
+
1323
+
1324
+
1325
+
1326
+
1327
+
1328
+
1329
+
1330
+
1331
+
1332
+
1333
+ * @example
1334
+ * // Access the maximum entry
1335
+ * const scores = new TreeMap<number, string>([
1336
+ * [85, 'Bob'],
1337
+ * [92, 'Alice'],
1338
+ * [78, 'Charlie']
1339
+ * ]);
1340
+ *
1341
+ * console.log(scores.last()); // [92, 'Alice'];
1342
+ * console.log(scores.first()); // [78, 'Charlie'];
352
1343
  */
353
1344
  last(): [K, V | undefined] | undefined {
354
1345
  const k = this.#core.getRightMost();
@@ -357,6 +1348,30 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
357
1348
 
358
1349
  /**
359
1350
  * Remove and return the smallest entry.
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1359
+
1360
+
1361
+
1362
+
1363
+ * @example
1364
+ * // Process items from lowest priority
1365
+ * const tasks = new TreeMap<number, string>([
1366
+ * [3, 'Low'],
1367
+ * [1, 'Critical'],
1368
+ * [2, 'Medium']
1369
+ * ]);
1370
+ *
1371
+ * // Process lowest priority first
1372
+ * console.log(tasks.pollFirst()); // [1, 'Critical'];
1373
+ * console.log(tasks.pollFirst()); // [2, 'Medium'];
1374
+ * console.log(tasks.size); // 1;
360
1375
  */
361
1376
  pollFirst(): [K, V | undefined] | undefined {
362
1377
  const entry = this.first();
@@ -367,6 +1382,30 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
367
1382
 
368
1383
  /**
369
1384
  * Remove and return the largest entry.
1385
+
1386
+
1387
+
1388
+
1389
+
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+
1396
+
1397
+ * @example
1398
+ * // Remove the maximum entry
1399
+ * const bids = new TreeMap<number, string>([
1400
+ * [100, 'Alice'],
1401
+ * [150, 'Bob'],
1402
+ * [120, 'Charlie']
1403
+ * ]);
1404
+ *
1405
+ * // Remove highest bid
1406
+ * console.log(bids.pollLast()); // [150, 'Bob'];
1407
+ * console.log(bids.size); // 2;
1408
+ * console.log(bids.last()); // [120, 'Charlie'];
370
1409
  */
371
1410
  pollLast(): [K, V | undefined] | undefined {
372
1411
  const entry = this.last();
@@ -377,6 +1416,79 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
377
1416
 
378
1417
  /**
379
1418
  * Smallest entry whose key is >= the given key.
1419
+
1420
+
1421
+
1422
+
1423
+
1424
+
1425
+
1426
+
1427
+
1428
+
1429
+
1430
+
1431
+
1432
+
1433
+
1434
+
1435
+
1436
+
1437
+
1438
+
1439
+
1440
+
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+
1448
+
1449
+
1450
+
1451
+
1452
+
1453
+
1454
+
1455
+
1456
+
1457
+
1458
+
1459
+
1460
+
1461
+ * @example
1462
+ * // Event scheduler with time-based lookup
1463
+ * const events = new TreeMap<Date, string>();
1464
+ *
1465
+ * const meeting = new Date('2024-01-15T10:00:00Z');
1466
+ * const lunch = new Date('2024-01-15T12:00:00Z');
1467
+ * const review = new Date('2024-01-15T15:00:00Z');
1468
+ * const standup = new Date('2024-01-15T09:00:00Z');
1469
+ *
1470
+ * events.set(meeting, 'Team Meeting');
1471
+ * events.set(lunch, 'Lunch Break');
1472
+ * events.set(review, 'Code Review');
1473
+ * events.set(standup, 'Daily Standup');
1474
+ *
1475
+ * // Events are sorted chronologically
1476
+ * console.log([...events.values()]); // [
1477
+ * // 'Daily Standup',
1478
+ * // 'Team Meeting',
1479
+ * // 'Lunch Break',
1480
+ * // 'Code Review'
1481
+ * // ];
1482
+ *
1483
+ * // Next event after 11:00
1484
+ * const after11 = new Date('2024-01-15T11:00:00Z');
1485
+ * console.log(events.ceiling(after11)?.[1]); // 'Lunch Break';
1486
+ *
1487
+ * // Events between 9:30 and 13:00
1488
+ * const from = new Date('2024-01-15T09:30:00Z');
1489
+ * const to = new Date('2024-01-15T13:00:00Z');
1490
+ * const window = events.rangeSearch([from, to]);
1491
+ * console.log(window.map(([, v]) => v)); // ['Team Meeting', 'Lunch Break'];
380
1492
  */
381
1493
  ceiling(key: K): [K, V | undefined] | undefined {
382
1494
  this._validateKey(key);
@@ -386,6 +1498,63 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
386
1498
 
387
1499
  /**
388
1500
  * Largest entry whose key is <= the given key.
1501
+
1502
+
1503
+
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+
1511
+
1512
+
1513
+
1514
+
1515
+
1516
+
1517
+
1518
+
1519
+
1520
+
1521
+
1522
+
1523
+
1524
+
1525
+
1526
+
1527
+
1528
+
1529
+
1530
+
1531
+
1532
+
1533
+
1534
+
1535
+
1536
+
1537
+
1538
+
1539
+
1540
+
1541
+
1542
+
1543
+ * @example
1544
+ * // Find the largest key ≤ target
1545
+ * const versions = new TreeMap<number, string>([
1546
+ * [1, 'v1.0'],
1547
+ * [3, 'v3.0'],
1548
+ * [5, 'v5.0'],
1549
+ * [7, 'v7.0']
1550
+ * ]);
1551
+ *
1552
+ * // Largest version ≤ 4
1553
+ * console.log(versions.floor(4)); // [3, 'v3.0'];
1554
+ * // Largest version ≤ 5 (exact match)
1555
+ * console.log(versions.floor(5)); // [5, 'v5.0'];
1556
+ * // No version ≤ 0
1557
+ * console.log(versions.floor(0)); // undefined;
389
1558
  */
390
1559
  floor(key: K): [K, V | undefined] | undefined {
391
1560
  this._validateKey(key);
@@ -395,6 +1564,63 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
395
1564
 
396
1565
  /**
397
1566
  * Smallest entry whose key is > the given key.
1567
+
1568
+
1569
+
1570
+
1571
+
1572
+
1573
+
1574
+
1575
+
1576
+
1577
+
1578
+
1579
+
1580
+
1581
+
1582
+
1583
+
1584
+
1585
+
1586
+
1587
+
1588
+
1589
+
1590
+
1591
+
1592
+
1593
+
1594
+
1595
+
1596
+
1597
+
1598
+
1599
+
1600
+
1601
+
1602
+
1603
+
1604
+
1605
+
1606
+
1607
+
1608
+
1609
+ * @example
1610
+ * // Find the smallest key strictly > target
1611
+ * const prices = new TreeMap<number, string>([
1612
+ * [10, 'Basic'],
1613
+ * [25, 'Standard'],
1614
+ * [50, 'Premium'],
1615
+ * [100, 'Enterprise']
1616
+ * ]);
1617
+ *
1618
+ * // Next tier above $25
1619
+ * console.log(prices.higher(25)); // [50, 'Premium'];
1620
+ * // Next tier above $99
1621
+ * console.log(prices.higher(99)); // [100, 'Enterprise'];
1622
+ * // Nothing above $100
1623
+ * console.log(prices.higher(100)); // undefined;
398
1624
  */
399
1625
  higher(key: K): [K, V | undefined] | undefined {
400
1626
  this._validateKey(key);
@@ -404,6 +1630,61 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
404
1630
 
405
1631
  /**
406
1632
  * Largest entry whose key is < the given key.
1633
+
1634
+
1635
+
1636
+
1637
+
1638
+
1639
+
1640
+
1641
+
1642
+
1643
+
1644
+
1645
+
1646
+
1647
+
1648
+
1649
+
1650
+
1651
+
1652
+
1653
+
1654
+
1655
+
1656
+
1657
+
1658
+
1659
+
1660
+
1661
+
1662
+
1663
+
1664
+
1665
+
1666
+
1667
+
1668
+
1669
+
1670
+
1671
+
1672
+
1673
+
1674
+
1675
+ * @example
1676
+ * // Find the largest key strictly < target
1677
+ * const temps = new TreeMap<number, string>([
1678
+ * [0, 'Freezing'],
1679
+ * [20, 'Cool'],
1680
+ * [30, 'Warm'],
1681
+ * [40, 'Hot']
1682
+ * ]);
1683
+ *
1684
+ * // Largest reading below 30
1685
+ * console.log(temps.lower(30)); // [20, 'Cool'];
1686
+ * // Nothing below 0
1687
+ * console.log(temps.lower(0)); // undefined;
407
1688
  */
408
1689
  lower(key: K): [K, V | undefined] | undefined {
409
1690
  this._validateKey(key);
@@ -416,6 +1697,78 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
416
1697
  *
417
1698
  * @param range `[low, high]`
418
1699
  * @param options Inclusive/exclusive bounds (defaults to inclusive).
1700
+
1701
+
1702
+
1703
+
1704
+
1705
+
1706
+
1707
+
1708
+
1709
+
1710
+
1711
+
1712
+
1713
+
1714
+
1715
+
1716
+
1717
+
1718
+
1719
+
1720
+
1721
+
1722
+
1723
+
1724
+
1725
+
1726
+
1727
+
1728
+
1729
+
1730
+
1731
+
1732
+
1733
+
1734
+
1735
+
1736
+
1737
+
1738
+
1739
+
1740
+
1741
+
1742
+ * @example
1743
+ * // Inventory system with price-sorted products
1744
+ * interface Product {
1745
+ * name: string;
1746
+ * price: number;
1747
+ * stock: number;
1748
+ * }
1749
+ *
1750
+ * const inventory = new TreeMap<string, Product, Product>(
1751
+ * [
1752
+ * { name: 'Widget', price: 9.99, stock: 100 },
1753
+ * { name: 'Gadget', price: 24.99, stock: 50 },
1754
+ * { name: 'Doohickey', price: 4.99, stock: 200 }
1755
+ * ],
1756
+ * { toEntryFn: p => [p.name, p] }
1757
+ * );
1758
+ *
1759
+ * // Sorted alphabetically by product name
1760
+ * console.log([...inventory.keys()]); // ['Doohickey', 'Gadget', 'Widget'];
1761
+ *
1762
+ * // Filter high-stock items
1763
+ * const highStock = inventory.filter(p => (p?.stock ?? 0) > 75);
1764
+ * console.log([...highStock.keys()]); // ['Doohickey', 'Widget'];
1765
+ *
1766
+ * // Calculate total inventory value
1767
+ * const totalValue = inventory.reduce(
1768
+ * (sum, p) => sum + (p ? p.price * p.stock : 0),
1769
+ * 0
1770
+ * );
1771
+ * console.log(totalValue); // toBeCloseTo;
419
1772
  */
420
1773
  rangeSearch(range: [K, K], options: TreeMapRangeOptions = {}): Array<[K, V | undefined]> {
421
1774
  const { lowInclusive = true, highInclusive = true } = options;
@@ -428,7 +1781,7 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
428
1781
  const cmp = this.#core.comparator;
429
1782
 
430
1783
  for (const k of keys) {
431
- if (k === undefined) continue;
1784
+ /* istanbul ignore next -- defensive: tree keys are never undefined */ if (k === undefined) continue;
432
1785
  if (!lowInclusive && cmp(k, low) === 0) continue;
433
1786
  if (!highInclusive && cmp(k, high) === 0) continue;
434
1787
  out.push(this._entryFromKey(k));
@@ -440,11 +1793,56 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
440
1793
  /**
441
1794
  * Creates a shallow clone of this map.
442
1795
  * @remarks Time O(n log n), Space O(n)
443
- * @example
444
- * const original = new TreeMap([['a', 1], ['b', 2]]);
445
- * const copy = original.clone();
446
- * copy.set('c', 3);
447
- * original.has('c'); // false (original unchanged)
1796
+
1797
+
1798
+
1799
+
1800
+
1801
+
1802
+
1803
+
1804
+
1805
+
1806
+
1807
+
1808
+
1809
+
1810
+
1811
+
1812
+
1813
+
1814
+
1815
+
1816
+
1817
+
1818
+
1819
+
1820
+
1821
+
1822
+
1823
+
1824
+
1825
+
1826
+
1827
+
1828
+
1829
+
1830
+
1831
+
1832
+
1833
+
1834
+
1835
+
1836
+
1837
+
1838
+
1839
+
1840
+ * @example
1841
+ * // Deep clone
1842
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
1843
+ * const copy = tm.clone();
1844
+ * copy.delete(1);
1845
+ * console.log(tm.has(1)); // true;
448
1846
  */
449
1847
  clone(): TreeMap<K, V> {
450
1848
  return new TreeMap<K, V>(this, {