max-priority-queue-typed 2.5.0 → 2.5.2

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 (90) hide show
  1. package/dist/cjs/index.cjs +398 -55
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +397 -54
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +398 -56
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +397 -55
  8. package/dist/esm-legacy/index.mjs.map +1 -1
  9. package/dist/types/common/error.d.ts +9 -0
  10. package/dist/types/common/index.d.ts +1 -1
  11. package/dist/types/data-structures/base/index.d.ts +1 -0
  12. package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
  13. package/dist/types/data-structures/base/linear-base.d.ts +3 -3
  14. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +288 -0
  15. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +336 -0
  16. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +618 -18
  17. package/dist/types/data-structures/binary-tree/bst.d.ts +676 -1
  18. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +456 -0
  19. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +144 -1
  20. package/dist/types/data-structures/binary-tree/tree-map.d.ts +3307 -399
  21. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3285 -360
  22. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2674 -325
  23. package/dist/types/data-structures/binary-tree/tree-set.d.ts +3072 -287
  24. package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
  25. package/dist/types/data-structures/graph/directed-graph.d.ts +240 -0
  26. package/dist/types/data-structures/graph/undirected-graph.d.ts +216 -0
  27. package/dist/types/data-structures/hash/hash-map.d.ts +274 -10
  28. package/dist/types/data-structures/heap/heap.d.ts +336 -0
  29. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +411 -3
  30. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +363 -3
  31. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +434 -2
  32. package/dist/types/data-structures/matrix/matrix.d.ts +192 -0
  33. package/dist/types/data-structures/queue/deque.d.ts +364 -4
  34. package/dist/types/data-structures/queue/queue.d.ts +288 -0
  35. package/dist/types/data-structures/stack/stack.d.ts +240 -0
  36. package/dist/types/data-structures/trie/trie.d.ts +292 -4
  37. package/dist/types/interfaces/graph.d.ts +1 -1
  38. package/dist/types/types/common.d.ts +2 -2
  39. package/dist/types/types/data-structures/binary-tree/bst.d.ts +1 -0
  40. package/dist/types/types/data-structures/binary-tree/tree-map.d.ts +5 -0
  41. package/dist/types/types/data-structures/binary-tree/tree-multi-set.d.ts +4 -0
  42. package/dist/types/types/data-structures/binary-tree/tree-set.d.ts +4 -0
  43. package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
  44. package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
  45. package/dist/types/types/utils/validate-type.d.ts +4 -4
  46. package/dist/umd/max-priority-queue-typed.js +395 -53
  47. package/dist/umd/max-priority-queue-typed.js.map +1 -1
  48. package/dist/umd/max-priority-queue-typed.min.js +1 -1
  49. package/dist/umd/max-priority-queue-typed.min.js.map +1 -1
  50. package/package.json +2 -2
  51. package/src/common/error.ts +19 -1
  52. package/src/common/index.ts +1 -1
  53. package/src/data-structures/base/index.ts +1 -0
  54. package/src/data-structures/base/iterable-element-base.ts +3 -2
  55. package/src/data-structures/base/iterable-entry-base.ts +8 -8
  56. package/src/data-structures/base/linear-base.ts +3 -3
  57. package/src/data-structures/binary-tree/avl-tree.ts +299 -0
  58. package/src/data-structures/binary-tree/binary-indexed-tree.ts +341 -5
  59. package/src/data-structures/binary-tree/binary-tree.ts +606 -6
  60. package/src/data-structures/binary-tree/bst.ts +946 -7
  61. package/src/data-structures/binary-tree/red-black-tree.ts +472 -0
  62. package/src/data-structures/binary-tree/segment-tree.ts +145 -2
  63. package/src/data-structures/binary-tree/tree-map.ts +3423 -499
  64. package/src/data-structures/binary-tree/tree-multi-map.ts +3537 -596
  65. package/src/data-structures/binary-tree/tree-multi-set.ts +2855 -495
  66. package/src/data-structures/binary-tree/tree-set.ts +3209 -413
  67. package/src/data-structures/graph/abstract-graph.ts +6 -6
  68. package/src/data-structures/graph/directed-graph.ts +240 -0
  69. package/src/data-structures/graph/undirected-graph.ts +216 -0
  70. package/src/data-structures/hash/hash-map.ts +281 -19
  71. package/src/data-structures/heap/heap.ts +340 -4
  72. package/src/data-structures/heap/max-heap.ts +2 -2
  73. package/src/data-structures/linked-list/doubly-linked-list.ts +411 -3
  74. package/src/data-structures/linked-list/singly-linked-list.ts +363 -3
  75. package/src/data-structures/linked-list/skip-linked-list.ts +439 -7
  76. package/src/data-structures/matrix/matrix.ts +202 -10
  77. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -2
  78. package/src/data-structures/queue/deque.ts +365 -5
  79. package/src/data-structures/queue/queue.ts +288 -0
  80. package/src/data-structures/stack/stack.ts +240 -0
  81. package/src/data-structures/trie/trie.ts +295 -7
  82. package/src/interfaces/graph.ts +1 -1
  83. package/src/types/common.ts +2 -2
  84. package/src/types/data-structures/binary-tree/bst.ts +1 -0
  85. package/src/types/data-structures/binary-tree/tree-map.ts +6 -0
  86. package/src/types/data-structures/binary-tree/tree-multi-set.ts +5 -0
  87. package/src/types/data-structures/binary-tree/tree-set.ts +5 -0
  88. package/src/types/data-structures/heap/heap.ts +1 -0
  89. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
  90. package/src/types/utils/validate-type.ts +4 -4
@@ -10,7 +10,7 @@
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
+ import { ERR, raise } from '../../common';
14
14
 
15
15
  /**
16
16
  * An ordered Map backed by a red-black tree.
@@ -52,7 +52,7 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
52
52
  const comparator = options.comparator ?? TreeMap.createDefaultComparator<K>();
53
53
  this.#isDefaultComparator = options.comparator === undefined;
54
54
 
55
- this.#core = new RedBlackTree<K, V>([], { comparator, isMapMode: options.isMapMode });
55
+ this.#core = new RedBlackTree<K, V>([], { comparator, isMapMode: options.isMapMode, enableOrderStatistic: options.enableOrderStatistic });
56
56
 
57
57
  for (const item of entries) {
58
58
  let k: K;
@@ -64,7 +64,7 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
64
64
  } else {
65
65
  // Validate entries like native Map: each item must be a 2-tuple-like value.
66
66
  if (!Array.isArray(item) || item.length < 2) {
67
- throw new TypeError(ERR.invalidEntry('TreeMap'));
67
+ raise(TypeError, ERR.invalidEntry('TreeMap'));
68
68
  }
69
69
  k = item[0] as K;
70
70
  v = item[1] as V | undefined;
@@ -88,7 +88,7 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
88
88
  return (a: K, b: K): number => {
89
89
  if (typeof a === 'number' && typeof b === 'number') {
90
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'));
91
+ if (Number.isNaN(a) || Number.isNaN(b)) raise(TypeError, ERR.invalidNaN('TreeMap'));
92
92
  const aa = Object.is(a, -0) ? 0 : a;
93
93
  const bb = Object.is(b, -0) ? 0 : b;
94
94
  return aa > bb ? 1 : aa < bb ? -1 : 0;
@@ -102,11 +102,11 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
102
102
  const ta = a.getTime();
103
103
  const tb = b.getTime();
104
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'));
105
+ if (Number.isNaN(ta) || Number.isNaN(tb)) raise(TypeError, ERR.invalidDate('TreeMap'));
106
106
  return ta > tb ? 1 : ta < tb ? -1 : 0;
107
107
  }
108
108
 
109
- throw new TypeError(ERR.comparatorRequired('TreeMap'));
109
+ raise(TypeError, ERR.comparatorRequired('TreeMap'));
110
110
  };
111
111
  }
112
112
 
@@ -114,18 +114,18 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
114
114
  if (!this.#isDefaultComparator) return;
115
115
 
116
116
  if (typeof key === 'number') {
117
- if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN('TreeMap'));
117
+ if (Number.isNaN(key)) raise(TypeError, ERR.invalidNaN('TreeMap'));
118
118
  return;
119
119
  }
120
120
 
121
121
  if (typeof key === 'string') return;
122
122
 
123
123
  if (key instanceof Date) {
124
- if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate('TreeMap'));
124
+ if (Number.isNaN(key.getTime())) raise(TypeError, ERR.invalidDate('TreeMap'));
125
125
  return;
126
126
  }
127
127
 
128
- throw new TypeError(ERR.comparatorRequired('TreeMap'));
128
+ raise(TypeError, ERR.comparatorRequired('TreeMap'));
129
129
  }
130
130
 
131
131
  /**
@@ -175,18 +175,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
175
175
 
176
176
 
177
177
 
178
- * @example
179
- * // Check empty
180
- * console.log(new TreeMap().isEmpty()); // true;
181
- */
182
- isEmpty(): boolean {
183
- return this.size === 0;
184
- }
185
-
186
- /**
187
- * Set or overwrite a value for a key.
188
- * @remarks Expected time O(log n)
189
-
190
178
 
191
179
 
192
180
 
@@ -233,39 +221,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
233
221
 
234
222
 
235
223
 
236
- * @example
237
- * // Sorted dictionary for a contact book
238
- * const contacts = new TreeMap<string, string>([
239
- * ['Bob', '555-0102'],
240
- * ['Alice', '555-0101'],
241
- * ['Charlie', '555-0103']
242
- * ]);
243
- *
244
- * // Contacts are automatically sorted by name
245
- * console.log([...contacts.keys()]); // ['Alice', 'Bob', 'Charlie'];
246
- * console.log(contacts.get('Bob')); // '555-0102';
247
- *
248
- * // Find the first contact alphabetically after 'B'
249
- * console.log(contacts.ceiling('B')); // ['Bob', '555-0102'];
250
- *
251
- * // Find contacts in range
252
- * console.log(contacts.rangeSearch(['Alice', 'Bob'])); // [
253
- * // ['Alice', '555-0101'],
254
- * // ['Bob', '555-0102']
255
- * // ];
256
- */
257
- set(key: K, value: V | undefined): this {
258
- this._validateKey(key);
259
- this.#core.set(key, value as V);
260
- return this;
261
- }
262
-
263
- /**
264
- * Get the value under a key.
265
- * @remarks Expected time O(log n)
266
-
267
-
268
-
269
224
 
270
225
 
271
226
 
@@ -312,26 +267,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
312
267
 
313
268
 
314
269
 
315
- * @example
316
- * // Configuration registry with typed lookups
317
- * const config = new TreeMap<string, number>([
318
- * ['maxRetries', 3],
319
- * ['timeout', 5000],
320
- * ['poolSize', 10]
321
- * ]);
322
- *
323
- * console.log(config.get('timeout')); // 5000;
324
- * console.log(config.get('missing')); // undefined;
325
- * console.log(config.size); // 3;
326
- */
327
- get(key: K): V | undefined {
328
- this._validateKey(key);
329
- return this.#core.get(key);
330
- }
331
-
332
- /**
333
- * Test whether a key exists.
334
- * @remarks Expected time O(log n)
335
270
 
336
271
 
337
272
 
@@ -360,6 +295,17 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
360
295
 
361
296
 
362
297
 
298
+ * @example
299
+ * // Check empty
300
+ * console.log(new TreeMap().isEmpty()); // true;
301
+ */
302
+ isEmpty(): boolean {
303
+ return this.size === 0;
304
+ }
305
+
306
+ /**
307
+ * Set or overwrite a value for a key.
308
+ * @remarks Expected time O(log n)
363
309
 
364
310
 
365
311
 
@@ -381,26 +327,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
381
327
 
382
328
 
383
329
 
384
- * @example
385
- * // Feature flag checking
386
- * const flags = new TreeMap<string, boolean>([
387
- * ['darkMode', true],
388
- * ['betaFeature', false],
389
- * ['notifications', true]
390
- * ]);
391
- *
392
- * console.log(flags.has('darkMode')); // true;
393
- * console.log(flags.has('unknownFlag')); // false;
394
- */
395
- has(key: K): boolean {
396
- this._validateKey(key);
397
- return this.#core.has(key);
398
- }
399
-
400
- /**
401
- * Delete a key.
402
- * @returns `true` if the key existed; otherwise `false`.
403
- * @remarks Expected time O(log n)
404
330
 
405
331
 
406
332
 
@@ -450,27 +376,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
450
376
 
451
377
 
452
378
 
453
- * @example
454
- * // Session management with expiry
455
- * const sessions = new TreeMap<string, number>([
456
- * ['sess_abc', Date.now()],
457
- * ['sess_def', Date.now()],
458
- * ['sess_ghi', Date.now()]
459
- * ]);
460
- *
461
- * console.log(sessions.size); // 3;
462
- * sessions.delete('sess_def');
463
- * console.log(sessions.has('sess_def')); // false;
464
- * console.log(sessions.size); // 2;
465
- */
466
- delete(key: K): boolean {
467
- this._validateKey(key);
468
- const res = this.#core.delete(key);
469
- return Array.isArray(res) && res.length > 0 && !!res[0]?.deleted;
470
- }
471
-
472
- /**
473
- * Remove all entries.
474
379
 
475
380
 
476
381
 
@@ -509,18 +414,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
509
414
 
510
415
 
511
416
 
512
- * @example
513
- * // Remove all
514
- * const tm = new TreeMap<number, string>([[1, 'a']]);
515
- * tm.clear();
516
- * console.log(tm.isEmpty()); // true;
517
- */
518
- clear(): void {
519
- this.#core.clear();
520
- }
521
-
522
- /**
523
- * Iterate over keys in ascending order.
524
417
 
525
418
 
526
419
 
@@ -559,25 +452,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
559
452
 
560
453
 
561
454
 
562
- * @example
563
- * // Get sorted keys
564
- * const tm = new TreeMap<number, string>([[3, 'c'], [1, 'a']]);
565
- * console.log([...tm.keys()]); // [1, 3];
566
- */
567
- keys(): IterableIterator<K> {
568
- return this.#core.keys();
569
- }
570
-
571
- private _entryFromKey(k: K): [K, V | undefined] {
572
- // Keys come from `keys()` which only yields existing keys.
573
- // We allow `undefined` as a stored value (native Map behavior), so entries are typed as `[K, V | undefined]`.
574
- return [k, this.#core.get(k)];
575
- }
576
-
577
- /**
578
- * Iterate over values in ascending key order.
579
- *
580
- * Note: values may be `undefined` (TreeMap allows storing `undefined`, like native `Map`).
581
455
 
582
456
 
583
457
 
@@ -599,6 +473,36 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
599
473
 
600
474
 
601
475
 
476
+ * @example
477
+ * // Sorted dictionary for a contact book
478
+ * const contacts = new TreeMap<string, string>([
479
+ * ['Bob', '555-0102'],
480
+ * ['Alice', '555-0101'],
481
+ * ['Charlie', '555-0103']
482
+ * ]);
483
+ *
484
+ * // Contacts are automatically sorted by name
485
+ * console.log([...contacts.keys()]); // ['Alice', 'Bob', 'Charlie'];
486
+ * console.log(contacts.get('Bob')); // '555-0102';
487
+ *
488
+ * // Find the first contact alphabetically after 'B'
489
+ * console.log(contacts.ceiling('B')); // ['Bob', '555-0102'];
490
+ *
491
+ * // Find contacts in range
492
+ * console.log(contacts.rangeSearch(['Alice', 'Bob'])); // [
493
+ * // ['Alice', '555-0101'],
494
+ * // ['Bob', '555-0102']
495
+ * // ];
496
+ */
497
+ set(key: K, value: V | undefined): this {
498
+ this._validateKey(key);
499
+ this.#core.set(key, value as V);
500
+ return this;
501
+ }
502
+
503
+ /**
504
+ * Get the value under a key.
505
+ * @remarks Expected time O(log n)
602
506
 
603
507
 
604
508
 
@@ -616,19 +520,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
616
520
 
617
521
 
618
522
 
619
- * @example
620
- * // Get values in key order
621
- * const tm = new TreeMap<number, string>([[2, 'b'], [1, 'a']]);
622
- * console.log([...tm.values()]); // ['a', 'b'];
623
- */
624
- *values(): IterableIterator<V | undefined> {
625
- for (const k of this.keys()) yield this._entryFromKey(k)[1];
626
- }
627
-
628
- /**
629
- * Iterate over `[key, value]` entries in ascending key order.
630
- *
631
- * Note: values may be `undefined`.
632
523
 
633
524
 
634
525
 
@@ -667,23 +558,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
667
558
 
668
559
 
669
560
 
670
- * @example
671
- * // Iterate key-value pairs
672
- * const tm = new TreeMap<number, string>([[3, 'c'], [1, 'a'], [2, 'b']]);
673
- * console.log([...tm.entries()]); // [[1, 'a'], [2, 'b'], [3, 'c']];
674
- */
675
- *entries(): IterableIterator<[K, V | undefined]> {
676
- for (const k of this.keys()) yield this._entryFromKey(k);
677
- }
678
-
679
- [Symbol.iterator](): IterableIterator<[K, V | undefined]> {
680
- return this.entries();
681
- }
682
-
683
- /**
684
- * Visit each entry in ascending key order.
685
- *
686
- * Note: callback value may be `undefined`.
687
561
 
688
562
 
689
563
 
@@ -722,22 +596,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
722
596
 
723
597
 
724
598
 
725
- * @example
726
- * // Execute for each entry
727
- * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
728
- * const pairs: string[] = [];
729
- * tm.forEach((v, k) => pairs.push(`${k}:${v}`));
730
- * console.log(pairs); // ['1:a', '2:b'];
731
- */
732
- forEach(cb: (value: V | undefined, key: K, map: TreeMap<K, V>) => void, thisArg?: any): void {
733
- for (const [k, v] of this) cb.call(thisArg, v, k, this);
734
- }
735
-
736
- /**
737
- * Create a new TreeMap by mapping each entry to a new `[key, value]` entry.
738
- *
739
- * This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
740
- * @remarks Time O(n log n) expected, Space O(n)
741
599
 
742
600
 
743
601
 
@@ -776,31 +634,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
776
634
 
777
635
 
778
636
 
779
- * @example
780
- * // Transform entries
781
- * const tm = new TreeMap<number, number>([[1, 10], [2, 20]]);
782
- * const doubled = tm.map((v, k) => [k, (v ?? 0) * 2] as [number, number]);
783
- * console.log([...doubled.values()]); // [20, 40];
784
- */
785
- map<MK, MV>(
786
- callbackfn: TreeMapEntryCallback<K, V, [MK, MV], TreeMap<K, V>>,
787
- options: Omit<TreeMapOptions<MK, MV>, 'toEntryFn'> & { comparator?: (a: MK, b: MK) => number } = {},
788
- thisArg?: unknown
789
- ): TreeMap<MK, MV> {
790
- const out = new TreeMap<MK, MV>([], options as TreeMapOptions<MK, MV>);
791
- let index = 0;
792
- for (const [k, v] of this) {
793
- const [mk, mv] = thisArg === undefined
794
- ? callbackfn(v, k, index++, this)
795
- : (callbackfn as (this: unknown, v: V | undefined, k: K, i: number, self: TreeMap<K, V>) => [MK, MV]).call(thisArg, v, k, index++, this);
796
- out.set(mk, mv);
797
- }
798
- return out;
799
- }
800
-
801
- /**
802
- * Create a new TreeMap containing only entries that satisfy the predicate.
803
- * @remarks Time O(n log n) expected, Space O(n)
804
637
 
805
638
 
806
639
 
@@ -840,26 +673,48 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
840
673
 
841
674
 
842
675
  * @example
843
- * // Filter entries
844
- * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b'], [3, 'c']]);
845
- * const filtered = tm.filter((v, k) => k > 1);
846
- * console.log([...filtered.keys()]); // [2, 3];
847
- */
848
- filter(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): TreeMap<K, V> {
849
- const out = new TreeMap<K, V>([], { comparator: this.#userComparator });
850
- let index = 0;
851
- for (const [k, v] of this) {
852
- const ok = thisArg === undefined
853
- ? callbackfn(v, k, index++, this)
854
- : (callbackfn as (this: unknown, v: V | undefined, k: K, i: number, self: TreeMap<K, V>) => boolean).call(thisArg, v, k, index++, this);
855
- if (ok) out.set(k, v);
856
- }
857
- return out;
676
+ * // Configuration registry with typed lookups
677
+ * const config = new TreeMap<string, number>([
678
+ * ['maxRetries', 3],
679
+ * ['timeout', 5000],
680
+ * ['poolSize', 10]
681
+ * ]);
682
+ *
683
+ * console.log(config.get('timeout')); // 5000;
684
+ * console.log(config.get('missing')); // undefined;
685
+ * console.log(config.size); // 3;
686
+ */
687
+ get(key: K): V | undefined {
688
+ this._validateKey(key);
689
+ return this.#core.get(key);
858
690
  }
859
691
 
860
692
  /**
861
- * Reduce entries into a single accumulator.
862
- * @remarks Time O(n), Space O(1)
693
+ * Test whether a key exists.
694
+ * @remarks Expected time O(log n)
695
+
696
+
697
+
698
+
699
+
700
+
701
+
702
+
703
+
704
+
705
+
706
+
707
+
708
+
709
+
710
+
711
+
712
+
713
+
714
+
715
+
716
+
717
+
863
718
 
864
719
 
865
720
 
@@ -898,21 +753,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
898
753
 
899
754
 
900
755
 
901
- * @example
902
- * // Aggregate values
903
- * const tm = new TreeMap<number, number>([[1, 10], [2, 20]]);
904
- * console.log(tm.reduce((acc, v) => acc + (v ?? 0), 0)); // 30;
905
- */
906
- reduce<A>(callbackfn: TreeMapReduceCallback<K, V, A, TreeMap<K, V>>, initialValue: A): A {
907
- let acc = initialValue;
908
- let index = 0;
909
- for (const [k, v] of this) acc = callbackfn(acc, v, k, index++, this);
910
- return acc;
911
- }
912
-
913
- /**
914
- * Test whether all entries satisfy a predicate.
915
- * @remarks Time O(n), Space O(1)
916
756
 
917
757
 
918
758
 
@@ -949,25 +789,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
949
789
 
950
790
 
951
791
 
952
- * @example
953
- * // Test all entries
954
- * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
955
- * console.log(tm.every((v, k) => k > 0)); // true;
956
- */
957
- every(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): boolean {
958
- let index = 0;
959
- for (const [k, v] of this) {
960
- const ok = thisArg === undefined
961
- ? callbackfn(v, k, index++, this)
962
- : (callbackfn as (this: unknown, v: V | undefined, k: K, i: number, self: TreeMap<K, V>) => boolean).call(thisArg, v, k, index++, this);
963
- if (!ok) return false;
964
- }
965
- return true;
966
- }
967
-
968
- /**
969
- * Test whether any entry satisfies a predicate.
970
- * @remarks Time O(n), Space O(1)
971
792
 
972
793
 
973
794
 
@@ -1004,26 +825,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1004
825
 
1005
826
 
1006
827
 
1007
- * @example
1008
- * // Test any entry
1009
- * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
1010
- * console.log(tm.some((v, k) => k === 2)); // true;
1011
- */
1012
- some(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): boolean {
1013
- let index = 0;
1014
- for (const [k, v] of this) {
1015
- const ok = thisArg === undefined
1016
- ? callbackfn(v, k, index++, this)
1017
- : (callbackfn as (this: unknown, v: V | undefined, k: K, i: number, self: TreeMap<K, V>) => boolean).call(thisArg, v, k, index++, this);
1018
- if (ok) return true;
1019
- }
1020
- return false;
1021
- }
1022
-
1023
- /**
1024
- * Find the first entry that satisfies a predicate.
1025
- * @returns The first matching `[key, value]` tuple, or `undefined`.
1026
- * @remarks Time O(n), Space O(1)
1027
828
 
1028
829
 
1029
830
 
@@ -1061,24 +862,25 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1061
862
 
1062
863
 
1063
864
  * @example
1064
- * // Find matching entry
1065
- * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
1066
- * console.log(tm.find(v => v === 'b')?.[0]); // 2;
865
+ * // Feature flag checking
866
+ * const flags = new TreeMap<string, boolean>([
867
+ * ['darkMode', true],
868
+ * ['betaFeature', false],
869
+ * ['notifications', true]
870
+ * ]);
871
+ *
872
+ * console.log(flags.has('darkMode')); // true;
873
+ * console.log(flags.has('unknownFlag')); // false;
1067
874
  */
1068
- find(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): [K, V | undefined] | undefined {
1069
- let index = 0;
1070
- for (const [k, v] of this) {
1071
- const ok = thisArg === undefined
1072
- ? callbackfn(v, k, index++, this)
1073
- : (callbackfn as (this: unknown, v: V | undefined, k: K, i: number, self: TreeMap<K, V>) => boolean).call(thisArg, v, k, index++, this);
1074
- if (ok) return [k, v];
1075
- }
1076
- return undefined;
875
+ has(key: K): boolean {
876
+ this._validateKey(key);
877
+ return this.#core.has(key);
1077
878
  }
1078
879
 
1079
880
  /**
1080
- * Materialize the map into an array of `[key, value]` tuples.
1081
- * @remarks Time O(n), Space O(n)
881
+ * Delete a key.
882
+ * @returns `true` if the key existed; otherwise `false`.
883
+ * @remarks Expected time O(log n)
1082
884
 
1083
885
 
1084
886
 
@@ -1117,18 +919,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1117
919
 
1118
920
 
1119
921
 
1120
- * @example
1121
- * // Convert to array
1122
- * const tm = new TreeMap<number, string>([[2, 'b'], [1, 'a']]);
1123
- * console.log(tm.toArray()); // [[1, 'a'], [2, 'b']];
1124
- */
1125
- toArray(): Array<[K, V | undefined]> {
1126
- return [...this];
1127
- }
1128
-
1129
- /**
1130
- * Print a human-friendly representation.
1131
- * @remarks Time O(n), Space O(n)
1132
922
 
1133
923
 
1134
924
 
@@ -1167,21 +957,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1167
957
 
1168
958
 
1169
959
 
1170
- * @example
1171
- * // Display tree
1172
- * const tm = new TreeMap<number, string>([[1, 'a']]);
1173
- * expect(() => tm.print()).not.toThrow();
1174
- */
1175
- print(): void {
1176
- // Delegate to the underlying tree's visualization.
1177
- this.#core.print();
1178
- }
1179
-
1180
- // Navigable operations (return entry tuples)
1181
- // Note: returned tuple values may be `undefined`.
1182
-
1183
- /**
1184
- * Smallest entry by key.
1185
960
 
1186
961
 
1187
962
 
@@ -1193,40 +968,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1193
968
 
1194
969
 
1195
970
 
1196
- * @example
1197
- * // Leaderboard with ranked scores
1198
- * // Use score as key (descending), player name as value
1199
- * const leaderboard = new TreeMap<number, string>([], {
1200
- * comparator: (a, b) => b - a // descending
1201
- * });
1202
- *
1203
- * leaderboard.set(1500, 'Alice');
1204
- * leaderboard.set(2200, 'Bob');
1205
- * leaderboard.set(1800, 'Charlie');
1206
- * leaderboard.set(2500, 'Diana');
1207
- *
1208
- * // Top 3 players (first 3 in descending order)
1209
- * const top3 = [...leaderboard.entries()].slice(0, 3);
1210
- * console.log(top3); // [
1211
- * // [2500, 'Diana'],
1212
- * // [2200, 'Bob'],
1213
- * // [1800, 'Charlie']
1214
- * // ];
1215
- *
1216
- * // Highest scorer
1217
- * console.log(leaderboard.first()); // [2500, 'Diana'];
1218
- *
1219
- * // Remove lowest scorer
1220
- * console.log(leaderboard.pollLast()); // [1500, 'Alice'];
1221
- * console.log(leaderboard.size); // 3;
1222
- */
1223
- first(): [K, V | undefined] | undefined {
1224
- const k = this.#core.getLeftMost();
1225
- return k === undefined ? undefined : this._entryFromKey(k);
1226
- }
1227
-
1228
- /**
1229
- * Largest entry by key.
1230
971
 
1231
972
 
1232
973
 
@@ -1238,24 +979,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1238
979
 
1239
980
 
1240
981
 
1241
- * @example
1242
- * // Access the maximum entry
1243
- * const scores = new TreeMap<number, string>([
1244
- * [85, 'Bob'],
1245
- * [92, 'Alice'],
1246
- * [78, 'Charlie']
1247
- * ]);
1248
- *
1249
- * console.log(scores.last()); // [92, 'Alice'];
1250
- * console.log(scores.first()); // [78, 'Charlie'];
1251
- */
1252
- last(): [K, V | undefined] | undefined {
1253
- const k = this.#core.getRightMost();
1254
- return k === undefined ? undefined : this._entryFromKey(k);
1255
- }
1256
-
1257
- /**
1258
- * Remove and return the smallest entry.
1259
982
 
1260
983
 
1261
984
 
@@ -1267,28 +990,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1267
990
 
1268
991
 
1269
992
 
1270
- * @example
1271
- * // Process items from lowest priority
1272
- * const tasks = new TreeMap<number, string>([
1273
- * [3, 'Low'],
1274
- * [1, 'Critical'],
1275
- * [2, 'Medium']
1276
- * ]);
1277
- *
1278
- * // Process lowest priority first
1279
- * console.log(tasks.pollFirst()); // [1, 'Critical'];
1280
- * console.log(tasks.pollFirst()); // [2, 'Medium'];
1281
- * console.log(tasks.size); // 1;
1282
- */
1283
- pollFirst(): [K, V | undefined] | undefined {
1284
- const entry = this.first();
1285
- if (!entry) return undefined;
1286
- this.delete(entry[0]);
1287
- return entry;
1288
- }
1289
-
1290
- /**
1291
- * Remove and return the largest entry.
1292
993
 
1293
994
 
1294
995
 
@@ -1300,28 +1001,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1300
1001
 
1301
1002
 
1302
1003
 
1303
- * @example
1304
- * // Remove the maximum entry
1305
- * const bids = new TreeMap<number, string>([
1306
- * [100, 'Alice'],
1307
- * [150, 'Bob'],
1308
- * [120, 'Charlie']
1309
- * ]);
1310
- *
1311
- * // Remove highest bid
1312
- * console.log(bids.pollLast()); // [150, 'Bob'];
1313
- * console.log(bids.size); // 2;
1314
- * console.log(bids.last()); // [120, 'Charlie'];
1315
- */
1316
- pollLast(): [K, V | undefined] | undefined {
1317
- const entry = this.last();
1318
- if (!entry) return undefined;
1319
- this.delete(entry[0]);
1320
- return entry;
1321
- }
1322
-
1323
- /**
1324
- * Smallest entry whose key is >= the given key.
1325
1004
 
1326
1005
 
1327
1006
 
@@ -1360,8 +1039,2681 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1360
1039
 
1361
1040
 
1362
1041
 
1363
- * @example
1364
- * // Event scheduler with time-based lookup
1042
+
1043
+
1044
+
1045
+
1046
+
1047
+
1048
+
1049
+
1050
+
1051
+
1052
+
1053
+ * @example
1054
+ * // Session management with expiry
1055
+ * const sessions = new TreeMap<string, number>([
1056
+ * ['sess_abc', Date.now()],
1057
+ * ['sess_def', Date.now()],
1058
+ * ['sess_ghi', Date.now()]
1059
+ * ]);
1060
+ *
1061
+ * console.log(sessions.size); // 3;
1062
+ * sessions.delete('sess_def');
1063
+ * console.log(sessions.has('sess_def')); // false;
1064
+ * console.log(sessions.size); // 2;
1065
+ */
1066
+ delete(key: K): boolean {
1067
+ this._validateKey(key);
1068
+ const res = this.#core.delete(key);
1069
+ return Array.isArray(res) && res.length > 0 && !!res[0]?.deleted;
1070
+ }
1071
+
1072
+ /**
1073
+ * Remove all entries.
1074
+
1075
+
1076
+
1077
+
1078
+
1079
+
1080
+
1081
+
1082
+
1083
+
1084
+
1085
+
1086
+
1087
+
1088
+
1089
+
1090
+
1091
+
1092
+
1093
+
1094
+
1095
+
1096
+
1097
+
1098
+
1099
+
1100
+
1101
+
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
+
1144
+
1145
+
1146
+
1147
+
1148
+
1149
+
1150
+
1151
+
1152
+
1153
+
1154
+
1155
+
1156
+
1157
+
1158
+
1159
+
1160
+
1161
+
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
+
1206
+
1207
+
1208
+
1209
+
1210
+
1211
+
1212
+
1213
+
1214
+
1215
+
1216
+
1217
+
1218
+
1219
+
1220
+
1221
+
1222
+
1223
+
1224
+
1225
+
1226
+
1227
+
1228
+
1229
+
1230
+
1231
+
1232
+ * @example
1233
+ * // Remove all
1234
+ * const tm = new TreeMap<number, string>([[1, 'a']]);
1235
+ * tm.clear();
1236
+ * console.log(tm.isEmpty()); // true;
1237
+ */
1238
+ clear(): void {
1239
+ this.#core.clear();
1240
+ }
1241
+
1242
+ /**
1243
+ * Iterate over keys in ascending order.
1244
+
1245
+
1246
+
1247
+
1248
+
1249
+
1250
+
1251
+
1252
+
1253
+
1254
+
1255
+
1256
+
1257
+
1258
+
1259
+
1260
+
1261
+
1262
+
1263
+
1264
+
1265
+
1266
+
1267
+
1268
+
1269
+
1270
+
1271
+
1272
+
1273
+
1274
+
1275
+
1276
+
1277
+
1278
+
1279
+
1280
+
1281
+
1282
+
1283
+
1284
+
1285
+
1286
+
1287
+
1288
+
1289
+
1290
+
1291
+
1292
+
1293
+
1294
+
1295
+
1296
+
1297
+
1298
+
1299
+
1300
+
1301
+
1302
+
1303
+
1304
+
1305
+
1306
+
1307
+
1308
+
1309
+
1310
+
1311
+
1312
+
1313
+
1314
+
1315
+
1316
+
1317
+
1318
+
1319
+
1320
+
1321
+
1322
+
1323
+
1324
+
1325
+
1326
+
1327
+
1328
+
1329
+
1330
+
1331
+
1332
+
1333
+
1334
+
1335
+
1336
+
1337
+
1338
+
1339
+
1340
+
1341
+
1342
+
1343
+
1344
+
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1359
+
1360
+
1361
+
1362
+
1363
+
1364
+
1365
+
1366
+
1367
+
1368
+
1369
+
1370
+
1371
+
1372
+
1373
+
1374
+
1375
+
1376
+
1377
+
1378
+
1379
+
1380
+
1381
+
1382
+
1383
+
1384
+
1385
+
1386
+
1387
+
1388
+
1389
+
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+
1396
+
1397
+
1398
+
1399
+
1400
+
1401
+
1402
+ * @example
1403
+ * // Get sorted keys
1404
+ * const tm = new TreeMap<number, string>([[3, 'c'], [1, 'a']]);
1405
+ * console.log([...tm.keys()]); // [1, 3];
1406
+ */
1407
+ keys(): IterableIterator<K> {
1408
+ return this.#core.keys();
1409
+ }
1410
+
1411
+ private _entryFromKey(k: K): [K, V | undefined] {
1412
+ // Keys come from `keys()` which only yields existing keys.
1413
+ // We allow `undefined` as a stored value (native Map behavior), so entries are typed as `[K, V | undefined]`.
1414
+ return [k, this.#core.get(k)];
1415
+ }
1416
+
1417
+ /**
1418
+ * Iterate over values in ascending key order.
1419
+ *
1420
+ * Note: values may be `undefined` (TreeMap allows storing `undefined`, like native `Map`).
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
+
1462
+
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+
1477
+
1478
+
1479
+
1480
+
1481
+
1482
+
1483
+
1484
+
1485
+
1486
+
1487
+
1488
+
1489
+
1490
+
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
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
+
1544
+
1545
+
1546
+
1547
+
1548
+
1549
+
1550
+
1551
+
1552
+
1553
+
1554
+
1555
+
1556
+
1557
+
1558
+
1559
+
1560
+
1561
+
1562
+
1563
+
1564
+
1565
+
1566
+
1567
+
1568
+
1569
+
1570
+
1571
+
1572
+
1573
+
1574
+
1575
+
1576
+
1577
+
1578
+
1579
+ * @example
1580
+ * // Get values in key order
1581
+ * const tm = new TreeMap<number, string>([[2, 'b'], [1, 'a']]);
1582
+ * console.log([...tm.values()]); // ['a', 'b'];
1583
+ */
1584
+ *values(): IterableIterator<V | undefined> {
1585
+ for (const k of this.keys()) yield this._entryFromKey(k)[1];
1586
+ }
1587
+
1588
+ /**
1589
+ * Iterate over `[key, value]` entries in ascending key order.
1590
+ *
1591
+ * Note: values may be `undefined`.
1592
+
1593
+
1594
+
1595
+
1596
+
1597
+
1598
+
1599
+
1600
+
1601
+
1602
+
1603
+
1604
+
1605
+
1606
+
1607
+
1608
+
1609
+
1610
+
1611
+
1612
+
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+
1620
+
1621
+
1622
+
1623
+
1624
+
1625
+
1626
+
1627
+
1628
+
1629
+
1630
+
1631
+
1632
+
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
+
1676
+
1677
+
1678
+
1679
+
1680
+
1681
+
1682
+
1683
+
1684
+
1685
+
1686
+
1687
+
1688
+
1689
+
1690
+
1691
+
1692
+
1693
+
1694
+
1695
+
1696
+
1697
+
1698
+
1699
+
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
+
1743
+
1744
+
1745
+
1746
+
1747
+
1748
+
1749
+
1750
+ * @example
1751
+ * // Iterate key-value pairs
1752
+ * const tm = new TreeMap<number, string>([[3, 'c'], [1, 'a'], [2, 'b']]);
1753
+ * console.log([...tm.entries()]); // [[1, 'a'], [2, 'b'], [3, 'c']];
1754
+ */
1755
+ *entries(): IterableIterator<[K, V | undefined]> {
1756
+ for (const k of this.keys()) yield this._entryFromKey(k);
1757
+ }
1758
+
1759
+ [Symbol.iterator](): IterableIterator<[K, V | undefined]> {
1760
+ return this.entries();
1761
+ }
1762
+
1763
+ /**
1764
+ * Visit each entry in ascending key order.
1765
+ *
1766
+ * Note: callback value may be `undefined`.
1767
+
1768
+
1769
+
1770
+
1771
+
1772
+
1773
+
1774
+
1775
+
1776
+
1777
+
1778
+
1779
+
1780
+
1781
+
1782
+
1783
+
1784
+
1785
+
1786
+
1787
+
1788
+
1789
+
1790
+
1791
+
1792
+
1793
+
1794
+
1795
+
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
+
1841
+
1842
+
1843
+
1844
+
1845
+
1846
+
1847
+
1848
+
1849
+
1850
+
1851
+
1852
+
1853
+
1854
+
1855
+
1856
+
1857
+
1858
+
1859
+
1860
+
1861
+
1862
+
1863
+
1864
+
1865
+
1866
+
1867
+
1868
+
1869
+
1870
+
1871
+
1872
+
1873
+
1874
+
1875
+
1876
+
1877
+
1878
+
1879
+
1880
+
1881
+
1882
+
1883
+
1884
+
1885
+
1886
+
1887
+
1888
+
1889
+
1890
+
1891
+
1892
+
1893
+
1894
+
1895
+
1896
+
1897
+
1898
+
1899
+
1900
+
1901
+
1902
+
1903
+
1904
+
1905
+
1906
+
1907
+
1908
+
1909
+
1910
+
1911
+
1912
+
1913
+
1914
+
1915
+
1916
+
1917
+
1918
+
1919
+
1920
+
1921
+
1922
+
1923
+
1924
+
1925
+ * @example
1926
+ * // Execute for each entry
1927
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
1928
+ * const pairs: string[] = [];
1929
+ * tm.forEach((v, k) => pairs.push(`${k}:${v}`));
1930
+ * console.log(pairs); // ['1:a', '2:b'];
1931
+ */
1932
+ forEach(cb: (value: V | undefined, key: K, map: TreeMap<K, V>) => void, thisArg?: unknown): void {
1933
+ for (const [k, v] of this) cb.call(thisArg, v, k, this);
1934
+ }
1935
+
1936
+ /**
1937
+ * Create a new TreeMap by mapping each entry to a new `[key, value]` entry.
1938
+ *
1939
+ * This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
1940
+ * @remarks Time O(n log n) expected, Space O(n)
1941
+
1942
+
1943
+
1944
+
1945
+
1946
+
1947
+
1948
+
1949
+
1950
+
1951
+
1952
+
1953
+
1954
+
1955
+
1956
+
1957
+
1958
+
1959
+
1960
+
1961
+
1962
+
1963
+
1964
+
1965
+
1966
+
1967
+
1968
+
1969
+
1970
+
1971
+
1972
+
1973
+
1974
+
1975
+
1976
+
1977
+
1978
+
1979
+
1980
+
1981
+
1982
+
1983
+
1984
+
1985
+
1986
+
1987
+
1988
+
1989
+
1990
+
1991
+
1992
+
1993
+
1994
+
1995
+
1996
+
1997
+
1998
+
1999
+
2000
+
2001
+
2002
+
2003
+
2004
+
2005
+
2006
+
2007
+
2008
+
2009
+
2010
+
2011
+
2012
+
2013
+
2014
+
2015
+
2016
+
2017
+
2018
+
2019
+
2020
+
2021
+
2022
+
2023
+
2024
+
2025
+
2026
+
2027
+
2028
+
2029
+
2030
+
2031
+
2032
+
2033
+
2034
+
2035
+
2036
+
2037
+
2038
+
2039
+
2040
+
2041
+
2042
+
2043
+
2044
+
2045
+
2046
+
2047
+
2048
+
2049
+
2050
+
2051
+
2052
+
2053
+
2054
+
2055
+
2056
+
2057
+
2058
+
2059
+
2060
+
2061
+
2062
+
2063
+
2064
+
2065
+
2066
+
2067
+
2068
+
2069
+
2070
+
2071
+
2072
+
2073
+
2074
+
2075
+
2076
+
2077
+
2078
+
2079
+
2080
+
2081
+
2082
+
2083
+
2084
+
2085
+
2086
+
2087
+
2088
+
2089
+
2090
+
2091
+
2092
+
2093
+
2094
+
2095
+
2096
+
2097
+
2098
+
2099
+ * @example
2100
+ * // Transform entries
2101
+ * const tm = new TreeMap<number, number>([[1, 10], [2, 20]]);
2102
+ * const doubled = tm.map((v, k) => [k, (v ?? 0) * 2] as [number, number]);
2103
+ * console.log([...doubled.values()]); // [20, 40];
2104
+ */
2105
+ map<MK, MV>(
2106
+ callbackfn: TreeMapEntryCallback<K, V, [MK, MV], TreeMap<K, V>>,
2107
+ options: Omit<TreeMapOptions<MK, MV>, 'toEntryFn'> & { comparator?: (a: MK, b: MK) => number } = {},
2108
+ thisArg?: unknown
2109
+ ): TreeMap<MK, MV> {
2110
+ const out = new TreeMap<MK, MV>([], options as TreeMapOptions<MK, MV>);
2111
+ let index = 0;
2112
+ for (const [k, v] of this) {
2113
+ const [mk, mv] = thisArg === undefined
2114
+ ? callbackfn(v, k, index++, this)
2115
+ : (callbackfn as (this: unknown, v: V | undefined, k: K, i: number, self: TreeMap<K, V>) => [MK, MV]).call(thisArg, v, k, index++, this);
2116
+ out.set(mk, mv);
2117
+ }
2118
+ return out;
2119
+ }
2120
+
2121
+ /**
2122
+ * Create a new TreeMap containing only entries that satisfy the predicate.
2123
+ * @remarks Time O(n log n) expected, Space O(n)
2124
+
2125
+
2126
+
2127
+
2128
+
2129
+
2130
+
2131
+
2132
+
2133
+
2134
+
2135
+
2136
+
2137
+
2138
+
2139
+
2140
+
2141
+
2142
+
2143
+
2144
+
2145
+
2146
+
2147
+
2148
+
2149
+
2150
+
2151
+
2152
+
2153
+
2154
+
2155
+
2156
+
2157
+
2158
+
2159
+
2160
+
2161
+
2162
+
2163
+
2164
+
2165
+
2166
+
2167
+
2168
+
2169
+
2170
+
2171
+
2172
+
2173
+
2174
+
2175
+
2176
+
2177
+
2178
+
2179
+
2180
+
2181
+
2182
+
2183
+
2184
+
2185
+
2186
+
2187
+
2188
+
2189
+
2190
+
2191
+
2192
+
2193
+
2194
+
2195
+
2196
+
2197
+
2198
+
2199
+
2200
+
2201
+
2202
+
2203
+
2204
+
2205
+
2206
+
2207
+
2208
+
2209
+
2210
+
2211
+
2212
+
2213
+
2214
+
2215
+
2216
+
2217
+
2218
+
2219
+
2220
+
2221
+
2222
+
2223
+
2224
+
2225
+
2226
+
2227
+
2228
+
2229
+
2230
+
2231
+
2232
+
2233
+
2234
+
2235
+
2236
+
2237
+
2238
+
2239
+
2240
+
2241
+
2242
+
2243
+
2244
+
2245
+
2246
+
2247
+
2248
+
2249
+
2250
+
2251
+
2252
+
2253
+
2254
+
2255
+
2256
+
2257
+
2258
+
2259
+
2260
+
2261
+
2262
+
2263
+
2264
+
2265
+
2266
+
2267
+
2268
+
2269
+
2270
+
2271
+
2272
+
2273
+
2274
+
2275
+
2276
+
2277
+
2278
+
2279
+
2280
+
2281
+
2282
+ * @example
2283
+ * // Filter entries
2284
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b'], [3, 'c']]);
2285
+ * const filtered = tm.filter((v, k) => k > 1);
2286
+ * console.log([...filtered.keys()]); // [2, 3];
2287
+ */
2288
+ filter(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): TreeMap<K, V> {
2289
+ const out = new TreeMap<K, V>([], { comparator: this.#userComparator });
2290
+ let index = 0;
2291
+ for (const [k, v] of this) {
2292
+ const ok = thisArg === undefined
2293
+ ? callbackfn(v, k, index++, this)
2294
+ : (callbackfn as (this: unknown, v: V | undefined, k: K, i: number, self: TreeMap<K, V>) => boolean).call(thisArg, v, k, index++, this);
2295
+ if (ok) out.set(k, v);
2296
+ }
2297
+ return out;
2298
+ }
2299
+
2300
+ /**
2301
+ * Reduce entries into a single accumulator.
2302
+ * @remarks Time O(n), Space O(1)
2303
+
2304
+
2305
+
2306
+
2307
+
2308
+
2309
+
2310
+
2311
+
2312
+
2313
+
2314
+
2315
+
2316
+
2317
+
2318
+
2319
+
2320
+
2321
+
2322
+
2323
+
2324
+
2325
+
2326
+
2327
+
2328
+
2329
+
2330
+
2331
+
2332
+
2333
+
2334
+
2335
+
2336
+
2337
+
2338
+
2339
+
2340
+
2341
+
2342
+
2343
+
2344
+
2345
+
2346
+
2347
+
2348
+
2349
+
2350
+
2351
+
2352
+
2353
+
2354
+
2355
+
2356
+
2357
+
2358
+
2359
+
2360
+
2361
+
2362
+
2363
+
2364
+
2365
+
2366
+
2367
+
2368
+
2369
+
2370
+
2371
+
2372
+
2373
+
2374
+
2375
+
2376
+
2377
+
2378
+
2379
+
2380
+
2381
+
2382
+
2383
+
2384
+
2385
+
2386
+
2387
+
2388
+
2389
+
2390
+
2391
+
2392
+
2393
+
2394
+
2395
+
2396
+
2397
+
2398
+
2399
+
2400
+
2401
+
2402
+
2403
+
2404
+
2405
+
2406
+
2407
+
2408
+
2409
+
2410
+
2411
+
2412
+
2413
+
2414
+
2415
+
2416
+
2417
+
2418
+
2419
+
2420
+
2421
+
2422
+
2423
+
2424
+
2425
+
2426
+
2427
+
2428
+
2429
+
2430
+
2431
+
2432
+
2433
+
2434
+
2435
+
2436
+
2437
+
2438
+
2439
+
2440
+
2441
+
2442
+
2443
+
2444
+
2445
+
2446
+
2447
+
2448
+
2449
+
2450
+
2451
+
2452
+
2453
+
2454
+
2455
+
2456
+
2457
+
2458
+
2459
+
2460
+
2461
+ * @example
2462
+ * // Aggregate values
2463
+ * const tm = new TreeMap<number, number>([[1, 10], [2, 20]]);
2464
+ * console.log(tm.reduce((acc, v) => acc + (v ?? 0), 0)); // 30;
2465
+ */
2466
+ reduce<A>(callbackfn: TreeMapReduceCallback<K, V, A, TreeMap<K, V>>, initialValue: A): A {
2467
+ let acc = initialValue;
2468
+ let index = 0;
2469
+ for (const [k, v] of this) acc = callbackfn(acc, v, k, index++, this);
2470
+ return acc;
2471
+ }
2472
+
2473
+ /**
2474
+ * Test whether all entries satisfy a predicate.
2475
+ * @remarks Time O(n), Space O(1)
2476
+
2477
+
2478
+
2479
+
2480
+
2481
+
2482
+
2483
+
2484
+
2485
+
2486
+
2487
+
2488
+
2489
+
2490
+
2491
+
2492
+
2493
+
2494
+
2495
+
2496
+
2497
+
2498
+
2499
+
2500
+
2501
+
2502
+
2503
+
2504
+
2505
+
2506
+
2507
+
2508
+
2509
+
2510
+
2511
+
2512
+
2513
+
2514
+
2515
+
2516
+
2517
+
2518
+
2519
+
2520
+
2521
+
2522
+
2523
+
2524
+
2525
+
2526
+
2527
+
2528
+
2529
+
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+
2538
+
2539
+
2540
+
2541
+
2542
+
2543
+
2544
+
2545
+
2546
+
2547
+
2548
+
2549
+
2550
+
2551
+
2552
+
2553
+
2554
+
2555
+
2556
+
2557
+
2558
+
2559
+
2560
+
2561
+
2562
+
2563
+
2564
+
2565
+
2566
+
2567
+
2568
+
2569
+
2570
+
2571
+
2572
+
2573
+
2574
+
2575
+
2576
+
2577
+
2578
+
2579
+
2580
+
2581
+
2582
+
2583
+
2584
+
2585
+
2586
+
2587
+
2588
+
2589
+
2590
+
2591
+
2592
+
2593
+
2594
+
2595
+
2596
+
2597
+
2598
+
2599
+
2600
+
2601
+
2602
+
2603
+
2604
+
2605
+
2606
+
2607
+
2608
+
2609
+
2610
+
2611
+
2612
+
2613
+
2614
+
2615
+
2616
+
2617
+
2618
+
2619
+
2620
+
2621
+
2622
+
2623
+
2624
+
2625
+
2626
+
2627
+
2628
+
2629
+
2630
+
2631
+
2632
+ * @example
2633
+ * // Test all entries
2634
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
2635
+ * console.log(tm.every((v, k) => k > 0)); // true;
2636
+ */
2637
+ every(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): boolean {
2638
+ let index = 0;
2639
+ for (const [k, v] of this) {
2640
+ const ok = thisArg === undefined
2641
+ ? callbackfn(v, k, index++, this)
2642
+ : (callbackfn as (this: unknown, v: V | undefined, k: K, i: number, self: TreeMap<K, V>) => boolean).call(thisArg, v, k, index++, this);
2643
+ if (!ok) return false;
2644
+ }
2645
+ return true;
2646
+ }
2647
+
2648
+ /**
2649
+ * Test whether any entry satisfies a predicate.
2650
+ * @remarks Time O(n), Space O(1)
2651
+
2652
+
2653
+
2654
+
2655
+
2656
+
2657
+
2658
+
2659
+
2660
+
2661
+
2662
+
2663
+
2664
+
2665
+
2666
+
2667
+
2668
+
2669
+
2670
+
2671
+
2672
+
2673
+
2674
+
2675
+
2676
+
2677
+
2678
+
2679
+
2680
+
2681
+
2682
+
2683
+
2684
+
2685
+
2686
+
2687
+
2688
+
2689
+
2690
+
2691
+
2692
+
2693
+
2694
+
2695
+
2696
+
2697
+
2698
+
2699
+
2700
+
2701
+
2702
+
2703
+
2704
+
2705
+
2706
+
2707
+
2708
+
2709
+
2710
+
2711
+
2712
+
2713
+
2714
+
2715
+
2716
+
2717
+
2718
+
2719
+
2720
+
2721
+
2722
+
2723
+
2724
+
2725
+
2726
+
2727
+
2728
+
2729
+
2730
+
2731
+
2732
+
2733
+
2734
+
2735
+
2736
+
2737
+
2738
+
2739
+
2740
+
2741
+
2742
+
2743
+
2744
+
2745
+
2746
+
2747
+
2748
+
2749
+
2750
+
2751
+
2752
+
2753
+
2754
+
2755
+
2756
+
2757
+
2758
+
2759
+
2760
+
2761
+
2762
+
2763
+
2764
+
2765
+
2766
+
2767
+
2768
+
2769
+
2770
+
2771
+
2772
+
2773
+
2774
+
2775
+
2776
+
2777
+
2778
+
2779
+
2780
+
2781
+
2782
+
2783
+
2784
+
2785
+
2786
+
2787
+
2788
+
2789
+
2790
+
2791
+
2792
+
2793
+
2794
+
2795
+
2796
+
2797
+
2798
+
2799
+
2800
+
2801
+
2802
+
2803
+
2804
+
2805
+
2806
+
2807
+ * @example
2808
+ * // Test any entry
2809
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
2810
+ * console.log(tm.some((v, k) => k === 2)); // true;
2811
+ */
2812
+ some(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): boolean {
2813
+ let index = 0;
2814
+ for (const [k, v] of this) {
2815
+ const ok = thisArg === undefined
2816
+ ? callbackfn(v, k, index++, this)
2817
+ : (callbackfn as (this: unknown, v: V | undefined, k: K, i: number, self: TreeMap<K, V>) => boolean).call(thisArg, v, k, index++, this);
2818
+ if (ok) return true;
2819
+ }
2820
+ return false;
2821
+ }
2822
+
2823
+ /**
2824
+ * Find the first entry that satisfies a predicate.
2825
+ * @returns The first matching `[key, value]` tuple, or `undefined`.
2826
+ * @remarks Time O(n), Space O(1)
2827
+
2828
+
2829
+
2830
+
2831
+
2832
+
2833
+
2834
+
2835
+
2836
+
2837
+
2838
+
2839
+
2840
+
2841
+
2842
+
2843
+
2844
+
2845
+
2846
+
2847
+
2848
+
2849
+
2850
+
2851
+
2852
+
2853
+
2854
+
2855
+
2856
+
2857
+
2858
+
2859
+
2860
+
2861
+
2862
+
2863
+
2864
+
2865
+
2866
+
2867
+
2868
+
2869
+
2870
+
2871
+
2872
+
2873
+
2874
+
2875
+
2876
+
2877
+
2878
+
2879
+
2880
+
2881
+
2882
+
2883
+
2884
+
2885
+
2886
+
2887
+
2888
+
2889
+
2890
+
2891
+
2892
+
2893
+
2894
+
2895
+
2896
+
2897
+
2898
+
2899
+
2900
+
2901
+
2902
+
2903
+
2904
+
2905
+
2906
+
2907
+
2908
+
2909
+
2910
+
2911
+
2912
+
2913
+
2914
+
2915
+
2916
+
2917
+
2918
+
2919
+
2920
+
2921
+
2922
+
2923
+
2924
+
2925
+
2926
+
2927
+
2928
+
2929
+
2930
+
2931
+
2932
+
2933
+
2934
+
2935
+
2936
+
2937
+
2938
+
2939
+
2940
+
2941
+
2942
+
2943
+
2944
+
2945
+
2946
+
2947
+
2948
+
2949
+
2950
+
2951
+
2952
+
2953
+
2954
+
2955
+
2956
+
2957
+
2958
+
2959
+
2960
+
2961
+
2962
+
2963
+
2964
+
2965
+
2966
+
2967
+
2968
+
2969
+
2970
+
2971
+
2972
+
2973
+
2974
+
2975
+
2976
+
2977
+
2978
+
2979
+
2980
+
2981
+
2982
+
2983
+ * @example
2984
+ * // Find matching entry
2985
+ * const tm = new TreeMap<number, string>([[1, 'a'], [2, 'b']]);
2986
+ * console.log(tm.find(v => v === 'b')?.[0]); // 2;
2987
+ */
2988
+ find(callbackfn: TreeMapEntryCallback<K, V, boolean, TreeMap<K, V>>, thisArg?: unknown): [K, V | undefined] | undefined {
2989
+ let index = 0;
2990
+ for (const [k, v] of this) {
2991
+ const ok = thisArg === undefined
2992
+ ? callbackfn(v, k, index++, this)
2993
+ : (callbackfn as (this: unknown, v: V | undefined, k: K, i: number, self: TreeMap<K, V>) => boolean).call(thisArg, v, k, index++, this);
2994
+ if (ok) return [k, v];
2995
+ }
2996
+ return undefined;
2997
+ }
2998
+
2999
+ /**
3000
+ * Materialize the map into an array of `[key, value]` tuples.
3001
+ * @remarks Time O(n), Space O(n)
3002
+
3003
+
3004
+
3005
+
3006
+
3007
+
3008
+
3009
+
3010
+
3011
+
3012
+
3013
+
3014
+
3015
+
3016
+
3017
+
3018
+
3019
+
3020
+
3021
+
3022
+
3023
+
3024
+
3025
+
3026
+
3027
+
3028
+
3029
+
3030
+
3031
+
3032
+
3033
+
3034
+
3035
+
3036
+
3037
+
3038
+
3039
+
3040
+
3041
+
3042
+
3043
+
3044
+
3045
+
3046
+
3047
+
3048
+
3049
+
3050
+
3051
+
3052
+
3053
+
3054
+
3055
+
3056
+
3057
+
3058
+
3059
+
3060
+
3061
+
3062
+
3063
+
3064
+
3065
+
3066
+
3067
+
3068
+
3069
+
3070
+
3071
+
3072
+
3073
+
3074
+
3075
+
3076
+
3077
+
3078
+
3079
+
3080
+
3081
+
3082
+
3083
+
3084
+
3085
+
3086
+
3087
+
3088
+
3089
+
3090
+
3091
+
3092
+
3093
+
3094
+
3095
+
3096
+
3097
+
3098
+
3099
+
3100
+
3101
+
3102
+
3103
+
3104
+
3105
+
3106
+
3107
+
3108
+
3109
+
3110
+
3111
+
3112
+
3113
+
3114
+
3115
+
3116
+
3117
+
3118
+
3119
+
3120
+
3121
+
3122
+
3123
+
3124
+
3125
+
3126
+
3127
+
3128
+
3129
+
3130
+
3131
+
3132
+
3133
+
3134
+
3135
+
3136
+
3137
+
3138
+
3139
+
3140
+
3141
+
3142
+
3143
+
3144
+
3145
+
3146
+
3147
+
3148
+
3149
+
3150
+
3151
+
3152
+
3153
+
3154
+
3155
+
3156
+
3157
+
3158
+
3159
+
3160
+ * @example
3161
+ * // Convert to array
3162
+ * const tm = new TreeMap<number, string>([[2, 'b'], [1, 'a']]);
3163
+ * console.log(tm.toArray()); // [[1, 'a'], [2, 'b']];
3164
+ */
3165
+ toArray(): Array<[K, V | undefined]> {
3166
+ return [...this];
3167
+ }
3168
+
3169
+ /**
3170
+ * Print a human-friendly representation.
3171
+ * @remarks Time O(n), Space O(n)
3172
+
3173
+
3174
+
3175
+
3176
+
3177
+
3178
+
3179
+
3180
+
3181
+
3182
+
3183
+
3184
+
3185
+
3186
+
3187
+
3188
+
3189
+
3190
+
3191
+
3192
+
3193
+
3194
+
3195
+
3196
+
3197
+
3198
+
3199
+
3200
+
3201
+
3202
+
3203
+
3204
+
3205
+
3206
+
3207
+
3208
+
3209
+
3210
+
3211
+
3212
+
3213
+
3214
+
3215
+
3216
+
3217
+
3218
+
3219
+
3220
+
3221
+
3222
+
3223
+
3224
+
3225
+
3226
+
3227
+
3228
+
3229
+
3230
+
3231
+
3232
+
3233
+
3234
+
3235
+
3236
+
3237
+
3238
+
3239
+
3240
+
3241
+
3242
+
3243
+
3244
+
3245
+
3246
+
3247
+
3248
+
3249
+
3250
+
3251
+
3252
+
3253
+
3254
+
3255
+
3256
+
3257
+
3258
+
3259
+
3260
+
3261
+
3262
+
3263
+
3264
+
3265
+
3266
+
3267
+
3268
+
3269
+
3270
+
3271
+
3272
+
3273
+
3274
+
3275
+
3276
+
3277
+
3278
+
3279
+
3280
+
3281
+
3282
+
3283
+
3284
+
3285
+
3286
+
3287
+
3288
+
3289
+
3290
+
3291
+
3292
+
3293
+
3294
+
3295
+
3296
+
3297
+
3298
+
3299
+
3300
+
3301
+
3302
+
3303
+
3304
+
3305
+
3306
+
3307
+
3308
+
3309
+
3310
+
3311
+
3312
+
3313
+
3314
+
3315
+
3316
+
3317
+
3318
+
3319
+
3320
+
3321
+
3322
+
3323
+
3324
+
3325
+
3326
+
3327
+
3328
+
3329
+
3330
+ * @example
3331
+ * // Display tree
3332
+ * const tm = new TreeMap<number, string>([[1, 'a']]);
3333
+ * expect(() => tm.print()).not.toThrow();
3334
+ */
3335
+ print(): void {
3336
+ // Delegate to the underlying tree's visualization.
3337
+ this.#core.print();
3338
+ }
3339
+
3340
+ // Navigable operations (return entry tuples)
3341
+ // Note: returned tuple values may be `undefined`.
3342
+
3343
+ /**
3344
+ * Smallest entry by key.
3345
+
3346
+
3347
+
3348
+
3349
+
3350
+
3351
+
3352
+
3353
+
3354
+
3355
+
3356
+
3357
+
3358
+
3359
+
3360
+
3361
+
3362
+
3363
+
3364
+
3365
+
3366
+
3367
+
3368
+
3369
+
3370
+
3371
+
3372
+
3373
+
3374
+
3375
+
3376
+
3377
+
3378
+
3379
+
3380
+ * @example
3381
+ * // Leaderboard with ranked scores
3382
+ * // Use score as key (descending), player name as value
3383
+ * const leaderboard = new TreeMap<number, string>([], {
3384
+ * comparator: (a, b) => b - a // descending
3385
+ * });
3386
+ *
3387
+ * leaderboard.set(1500, 'Alice');
3388
+ * leaderboard.set(2200, 'Bob');
3389
+ * leaderboard.set(1800, 'Charlie');
3390
+ * leaderboard.set(2500, 'Diana');
3391
+ *
3392
+ * // Top 3 players (first 3 in descending order)
3393
+ * const top3 = [...leaderboard.entries()].slice(0, 3);
3394
+ * console.log(top3); // [
3395
+ * // [2500, 'Diana'],
3396
+ * // [2200, 'Bob'],
3397
+ * // [1800, 'Charlie']
3398
+ * // ];
3399
+ *
3400
+ * // Highest scorer
3401
+ * console.log(leaderboard.first()); // [2500, 'Diana'];
3402
+ *
3403
+ * // Remove lowest scorer
3404
+ * console.log(leaderboard.pollLast()); // [1500, 'Alice'];
3405
+ * console.log(leaderboard.size); // 3;
3406
+ */
3407
+ first(): [K, V | undefined] | undefined {
3408
+ const k = this.#core.getLeftMost();
3409
+ return k === undefined ? undefined : this._entryFromKey(k);
3410
+ }
3411
+
3412
+ /**
3413
+ * Largest entry by key.
3414
+
3415
+
3416
+
3417
+
3418
+
3419
+
3420
+
3421
+
3422
+
3423
+
3424
+
3425
+
3426
+
3427
+
3428
+
3429
+
3430
+
3431
+
3432
+
3433
+
3434
+
3435
+
3436
+
3437
+
3438
+
3439
+
3440
+
3441
+
3442
+
3443
+
3444
+
3445
+
3446
+
3447
+
3448
+
3449
+ * @example
3450
+ * // Access the maximum entry
3451
+ * const scores = new TreeMap<number, string>([
3452
+ * [85, 'Bob'],
3453
+ * [92, 'Alice'],
3454
+ * [78, 'Charlie']
3455
+ * ]);
3456
+ *
3457
+ * console.log(scores.last()); // [92, 'Alice'];
3458
+ * console.log(scores.first()); // [78, 'Charlie'];
3459
+ */
3460
+ last(): [K, V | undefined] | undefined {
3461
+ const k = this.#core.getRightMost();
3462
+ return k === undefined ? undefined : this._entryFromKey(k);
3463
+ }
3464
+
3465
+ /**
3466
+ * Remove and return the smallest entry.
3467
+
3468
+
3469
+
3470
+
3471
+
3472
+
3473
+
3474
+
3475
+
3476
+
3477
+
3478
+
3479
+
3480
+
3481
+
3482
+
3483
+
3484
+
3485
+
3486
+
3487
+
3488
+
3489
+
3490
+
3491
+
3492
+
3493
+
3494
+
3495
+
3496
+
3497
+
3498
+
3499
+
3500
+
3501
+
3502
+ * @example
3503
+ * // Process items from lowest priority
3504
+ * const tasks = new TreeMap<number, string>([
3505
+ * [3, 'Low'],
3506
+ * [1, 'Critical'],
3507
+ * [2, 'Medium']
3508
+ * ]);
3509
+ *
3510
+ * // Process lowest priority first
3511
+ * console.log(tasks.pollFirst()); // [1, 'Critical'];
3512
+ * console.log(tasks.pollFirst()); // [2, 'Medium'];
3513
+ * console.log(tasks.size); // 1;
3514
+ */
3515
+ pollFirst(): [K, V | undefined] | undefined {
3516
+ const entry = this.first();
3517
+ if (!entry) return undefined;
3518
+ this.delete(entry[0]);
3519
+ return entry;
3520
+ }
3521
+
3522
+ /**
3523
+ * Remove and return the largest entry.
3524
+
3525
+
3526
+
3527
+
3528
+
3529
+
3530
+
3531
+
3532
+
3533
+
3534
+
3535
+
3536
+
3537
+
3538
+
3539
+
3540
+
3541
+
3542
+
3543
+
3544
+
3545
+
3546
+
3547
+
3548
+
3549
+
3550
+
3551
+
3552
+
3553
+
3554
+
3555
+
3556
+
3557
+
3558
+
3559
+ * @example
3560
+ * // Remove the maximum entry
3561
+ * const bids = new TreeMap<number, string>([
3562
+ * [100, 'Alice'],
3563
+ * [150, 'Bob'],
3564
+ * [120, 'Charlie']
3565
+ * ]);
3566
+ *
3567
+ * // Remove highest bid
3568
+ * console.log(bids.pollLast()); // [150, 'Bob'];
3569
+ * console.log(bids.size); // 2;
3570
+ * console.log(bids.last()); // [120, 'Charlie'];
3571
+ */
3572
+ pollLast(): [K, V | undefined] | undefined {
3573
+ const entry = this.last();
3574
+ if (!entry) return undefined;
3575
+ this.delete(entry[0]);
3576
+ return entry;
3577
+ }
3578
+
3579
+ /**
3580
+ * Smallest entry whose key is >= the given key.
3581
+
3582
+
3583
+
3584
+
3585
+
3586
+
3587
+
3588
+
3589
+
3590
+
3591
+
3592
+
3593
+
3594
+
3595
+
3596
+
3597
+
3598
+
3599
+
3600
+
3601
+
3602
+
3603
+
3604
+
3605
+
3606
+
3607
+
3608
+
3609
+
3610
+
3611
+
3612
+
3613
+
3614
+
3615
+
3616
+
3617
+
3618
+
3619
+
3620
+
3621
+
3622
+
3623
+
3624
+
3625
+
3626
+
3627
+
3628
+
3629
+
3630
+
3631
+
3632
+
3633
+
3634
+
3635
+
3636
+
3637
+
3638
+
3639
+
3640
+
3641
+
3642
+
3643
+
3644
+
3645
+
3646
+
3647
+
3648
+
3649
+
3650
+
3651
+
3652
+
3653
+
3654
+
3655
+
3656
+
3657
+
3658
+
3659
+
3660
+
3661
+
3662
+
3663
+
3664
+
3665
+
3666
+
3667
+
3668
+
3669
+
3670
+
3671
+
3672
+
3673
+
3674
+
3675
+
3676
+
3677
+
3678
+
3679
+
3680
+
3681
+
3682
+
3683
+
3684
+
3685
+
3686
+
3687
+
3688
+
3689
+
3690
+
3691
+
3692
+
3693
+
3694
+
3695
+
3696
+
3697
+
3698
+
3699
+
3700
+
3701
+
3702
+
3703
+
3704
+
3705
+
3706
+
3707
+
3708
+
3709
+
3710
+
3711
+
3712
+
3713
+
3714
+
3715
+ * @example
3716
+ * // Event scheduler with time-based lookup
1365
3717
  * const events = new TreeMap<Date, string>();
1366
3718
  *
1367
3719
  * const meeting = new Date('2024-01-15T10:00:00Z');
@@ -1386,20 +3738,432 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1386
3738
  * const after11 = new Date('2024-01-15T11:00:00Z');
1387
3739
  * console.log(events.ceiling(after11)?.[1]); // 'Lunch Break';
1388
3740
  *
1389
- * // Events between 9:30 and 13:00
1390
- * const from = new Date('2024-01-15T09:30:00Z');
1391
- * const to = new Date('2024-01-15T13:00:00Z');
1392
- * const window = events.rangeSearch([from, to]);
1393
- * console.log(window.map(([, v]) => v)); // ['Team Meeting', 'Lunch Break'];
3741
+ * // Events between 9:30 and 13:00
3742
+ * const from = new Date('2024-01-15T09:30:00Z');
3743
+ * const to = new Date('2024-01-15T13:00:00Z');
3744
+ * const window = events.rangeSearch([from, to]);
3745
+ * console.log(window.map(([, v]) => v)); // ['Team Meeting', 'Lunch Break'];
3746
+ */
3747
+ ceiling(key: K): [K, V | undefined] | undefined {
3748
+ this._validateKey(key);
3749
+ const k = this.#core.ceiling(key);
3750
+ return k === undefined ? undefined : this._entryFromKey(k);
3751
+ }
3752
+
3753
+ /**
3754
+ * Largest entry whose key is <= the given key.
3755
+
3756
+
3757
+
3758
+
3759
+
3760
+
3761
+
3762
+
3763
+
3764
+
3765
+
3766
+
3767
+
3768
+
3769
+
3770
+
3771
+
3772
+
3773
+
3774
+
3775
+
3776
+
3777
+
3778
+
3779
+
3780
+
3781
+
3782
+
3783
+
3784
+
3785
+
3786
+
3787
+
3788
+
3789
+
3790
+
3791
+
3792
+
3793
+
3794
+
3795
+
3796
+
3797
+
3798
+
3799
+
3800
+
3801
+
3802
+
3803
+
3804
+
3805
+
3806
+
3807
+
3808
+
3809
+
3810
+
3811
+
3812
+
3813
+
3814
+
3815
+
3816
+
3817
+
3818
+
3819
+
3820
+
3821
+
3822
+
3823
+
3824
+
3825
+
3826
+
3827
+
3828
+
3829
+
3830
+
3831
+
3832
+
3833
+
3834
+
3835
+
3836
+
3837
+
3838
+
3839
+
3840
+
3841
+
3842
+
3843
+
3844
+
3845
+
3846
+
3847
+
3848
+
3849
+
3850
+
3851
+
3852
+
3853
+
3854
+
3855
+
3856
+
3857
+
3858
+
3859
+
3860
+
3861
+
3862
+
3863
+
3864
+
3865
+
3866
+
3867
+
3868
+
3869
+
3870
+
3871
+
3872
+
3873
+
3874
+
3875
+
3876
+
3877
+
3878
+
3879
+
3880
+
3881
+
3882
+
3883
+
3884
+
3885
+
3886
+
3887
+
3888
+
3889
+ * @example
3890
+ * // Find the largest key ≤ target
3891
+ * const versions = new TreeMap<number, string>([
3892
+ * [1, 'v1.0'],
3893
+ * [3, 'v3.0'],
3894
+ * [5, 'v5.0'],
3895
+ * [7, 'v7.0']
3896
+ * ]);
3897
+ *
3898
+ * // Largest version ≤ 4
3899
+ * console.log(versions.floor(4)); // [3, 'v3.0'];
3900
+ * // Largest version ≤ 5 (exact match)
3901
+ * console.log(versions.floor(5)); // [5, 'v5.0'];
3902
+ * // No version ≤ 0
3903
+ * console.log(versions.floor(0)); // undefined;
1394
3904
  */
1395
- ceiling(key: K): [K, V | undefined] | undefined {
3905
+ floor(key: K): [K, V | undefined] | undefined {
1396
3906
  this._validateKey(key);
1397
- const k = this.#core.ceiling(key);
3907
+ const k = this.#core.floor(key);
1398
3908
  return k === undefined ? undefined : this._entryFromKey(k);
1399
3909
  }
1400
3910
 
1401
3911
  /**
1402
- * Largest entry whose key is <= the given key.
3912
+ * Smallest entry whose key is > the given key.
3913
+
3914
+
3915
+
3916
+
3917
+
3918
+
3919
+
3920
+
3921
+
3922
+
3923
+
3924
+
3925
+
3926
+
3927
+
3928
+
3929
+
3930
+
3931
+
3932
+
3933
+
3934
+
3935
+
3936
+
3937
+
3938
+
3939
+
3940
+
3941
+
3942
+
3943
+
3944
+
3945
+
3946
+
3947
+
3948
+
3949
+
3950
+
3951
+
3952
+
3953
+
3954
+
3955
+
3956
+
3957
+
3958
+
3959
+
3960
+
3961
+
3962
+
3963
+
3964
+
3965
+
3966
+
3967
+
3968
+
3969
+
3970
+
3971
+
3972
+
3973
+
3974
+
3975
+
3976
+
3977
+
3978
+
3979
+
3980
+
3981
+
3982
+
3983
+
3984
+
3985
+
3986
+
3987
+
3988
+
3989
+
3990
+
3991
+
3992
+
3993
+
3994
+
3995
+
3996
+
3997
+
3998
+
3999
+
4000
+
4001
+
4002
+
4003
+
4004
+
4005
+
4006
+
4007
+
4008
+
4009
+
4010
+
4011
+
4012
+
4013
+
4014
+
4015
+
4016
+
4017
+
4018
+
4019
+
4020
+
4021
+
4022
+
4023
+
4024
+
4025
+
4026
+
4027
+
4028
+
4029
+
4030
+
4031
+
4032
+
4033
+
4034
+
4035
+
4036
+
4037
+
4038
+
4039
+
4040
+
4041
+
4042
+
4043
+
4044
+
4045
+
4046
+
4047
+ * @example
4048
+ * // Find the smallest key strictly > target
4049
+ * const prices = new TreeMap<number, string>([
4050
+ * [10, 'Basic'],
4051
+ * [25, 'Standard'],
4052
+ * [50, 'Premium'],
4053
+ * [100, 'Enterprise']
4054
+ * ]);
4055
+ *
4056
+ * // Next tier above $25
4057
+ * console.log(prices.higher(25)); // [50, 'Premium'];
4058
+ * // Next tier above $99
4059
+ * console.log(prices.higher(99)); // [100, 'Enterprise'];
4060
+ * // Nothing above $100
4061
+ * console.log(prices.higher(100)); // undefined;
4062
+ */
4063
+ higher(key: K): [K, V | undefined] | undefined {
4064
+ this._validateKey(key);
4065
+ const k = this.#core.higher(key);
4066
+ return k === undefined ? undefined : this._entryFromKey(k);
4067
+ }
4068
+
4069
+ /**
4070
+ * Largest entry whose key is < the given key.
4071
+
4072
+
4073
+
4074
+
4075
+
4076
+
4077
+
4078
+
4079
+
4080
+
4081
+
4082
+
4083
+
4084
+
4085
+
4086
+
4087
+
4088
+
4089
+
4090
+
4091
+
4092
+
4093
+
4094
+
4095
+
4096
+
4097
+
4098
+
4099
+
4100
+
4101
+
4102
+
4103
+
4104
+
4105
+
4106
+
4107
+
4108
+
4109
+
4110
+
4111
+
4112
+
4113
+
4114
+
4115
+
4116
+
4117
+
4118
+
4119
+
4120
+
4121
+
4122
+
4123
+
4124
+
4125
+
4126
+
4127
+
4128
+
4129
+
4130
+
4131
+
4132
+
4133
+
4134
+
4135
+
4136
+
4137
+
4138
+
4139
+
4140
+
4141
+
4142
+
4143
+
4144
+
4145
+
4146
+
4147
+
4148
+
4149
+
4150
+
4151
+
4152
+
4153
+
4154
+
4155
+
4156
+
4157
+
4158
+
4159
+
4160
+
4161
+
4162
+
4163
+
4164
+
4165
+
4166
+
1403
4167
 
1404
4168
 
1405
4169
 
@@ -1439,29 +4203,50 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1439
4203
 
1440
4204
 
1441
4205
  * @example
1442
- * // Find the largest key target
1443
- * const versions = new TreeMap<number, string>([
1444
- * [1, 'v1.0'],
1445
- * [3, 'v3.0'],
1446
- * [5, 'v5.0'],
1447
- * [7, 'v7.0']
4206
+ * // Find the largest key strictly < target
4207
+ * const temps = new TreeMap<number, string>([
4208
+ * [0, 'Freezing'],
4209
+ * [20, 'Cool'],
4210
+ * [30, 'Warm'],
4211
+ * [40, 'Hot']
1448
4212
  * ]);
1449
4213
  *
1450
- * // Largest version 4
1451
- * console.log(versions.floor(4)); // [3, 'v3.0'];
1452
- * // Largest version ≤ 5 (exact match)
1453
- * console.log(versions.floor(5)); // [5, 'v5.0'];
1454
- * // No version ≤ 0
1455
- * console.log(versions.floor(0)); // undefined;
4214
+ * // Largest reading below 30
4215
+ * console.log(temps.lower(30)); // [20, 'Cool'];
4216
+ * // Nothing below 0
4217
+ * console.log(temps.lower(0)); // undefined;
1456
4218
  */
1457
- floor(key: K): [K, V | undefined] | undefined {
4219
+ lower(key: K): [K, V | undefined] | undefined {
1458
4220
  this._validateKey(key);
1459
- const k = this.#core.floor(key);
4221
+ const k = this.#core.lower(key);
1460
4222
  return k === undefined ? undefined : this._entryFromKey(k);
1461
4223
  }
1462
4224
 
1463
4225
  /**
1464
- * Smallest entry whose key is > the given key.
4226
+ * Return all entries in a given key range.
4227
+ *
4228
+ * @param range `[low, high]`
4229
+ * @param options Inclusive/exclusive bounds (defaults to inclusive).
4230
+
4231
+
4232
+
4233
+
4234
+
4235
+
4236
+
4237
+
4238
+
4239
+
4240
+
4241
+
4242
+
4243
+
4244
+
4245
+
4246
+
4247
+
4248
+
4249
+
1465
4250
 
1466
4251
 
1467
4252
 
@@ -1500,30 +4285,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1500
4285
 
1501
4286
 
1502
4287
 
1503
- * @example
1504
- * // Find the smallest key strictly > target
1505
- * const prices = new TreeMap<number, string>([
1506
- * [10, 'Basic'],
1507
- * [25, 'Standard'],
1508
- * [50, 'Premium'],
1509
- * [100, 'Enterprise']
1510
- * ]);
1511
- *
1512
- * // Next tier above $25
1513
- * console.log(prices.higher(25)); // [50, 'Premium'];
1514
- * // Next tier above $99
1515
- * console.log(prices.higher(99)); // [100, 'Enterprise'];
1516
- * // Nothing above $100
1517
- * console.log(prices.higher(100)); // undefined;
1518
- */
1519
- higher(key: K): [K, V | undefined] | undefined {
1520
- this._validateKey(key);
1521
- const k = this.#core.higher(key);
1522
- return k === undefined ? undefined : this._entryFromKey(k);
1523
- }
1524
-
1525
- /**
1526
- * Largest entry whose key is < the given key.
1527
4288
 
1528
4289
 
1529
4290
 
@@ -1562,31 +4323,6 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1562
4323
 
1563
4324
 
1564
4325
 
1565
- * @example
1566
- * // Find the largest key strictly < target
1567
- * const temps = new TreeMap<number, string>([
1568
- * [0, 'Freezing'],
1569
- * [20, 'Cool'],
1570
- * [30, 'Warm'],
1571
- * [40, 'Hot']
1572
- * ]);
1573
- *
1574
- * // Largest reading below 30
1575
- * console.log(temps.lower(30)); // [20, 'Cool'];
1576
- * // Nothing below 0
1577
- * console.log(temps.lower(0)); // undefined;
1578
- */
1579
- lower(key: K): [K, V | undefined] | undefined {
1580
- this._validateKey(key);
1581
- const k = this.#core.lower(key);
1582
- return k === undefined ? undefined : this._entryFromKey(k);
1583
- }
1584
-
1585
- /**
1586
- * Return all entries in a given key range.
1587
- *
1588
- * @param range `[low, high]`
1589
- * @param options Inclusive/exclusive bounds (defaults to inclusive).
1590
4326
 
1591
4327
 
1592
4328
 
@@ -1676,6 +4412,74 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1676
4412
  return out;
1677
4413
  }
1678
4414
 
4415
+ // ─── Order-Statistic Methods ───────────────────────────
4416
+
4417
+ /**
4418
+ * Returns the entry at the k-th position in tree order (0-indexed).
4419
+ * @remarks Time O(log n). Requires `enableOrderStatistic: true`.
4420
+
4421
+
4422
+
4423
+ * @example
4424
+ * // Find k-th entry in a TreeMap
4425
+ * const map = new TreeMap<string, number>(
4426
+ * [['alice', 95], ['bob', 87], ['charlie', 92]],
4427
+ * { enableOrderStatistic: true }
4428
+ * );
4429
+ * console.log(map.getByRank(0)); // 'alice';
4430
+ * console.log(map.getByRank(1)); // 'bob';
4431
+ * console.log(map.getByRank(2)); // 'charlie';
4432
+ */
4433
+ getByRank(k: number): [K, V | undefined] | undefined {
4434
+ const key = this.#core.getByRank(k);
4435
+ if (key === undefined) return undefined;
4436
+ return [key, this.#core.get(key)];
4437
+ }
4438
+
4439
+ /**
4440
+ * Returns the 0-based rank of a key (number of elements that precede it in tree order).
4441
+ * @remarks Time O(log n). Requires `enableOrderStatistic: true`.
4442
+ * @example
4443
+ * // Get the rank of a key in sorted order
4444
+ * const tree = new TreeMap<number>(
4445
+ * [10, 20, 30, 40, 50],
4446
+ * { enableOrderStatistic: true }
4447
+ * );
4448
+ * console.log(tree.getRank(10)); // 0; // smallest → rank 0
4449
+ * console.log(tree.getRank(30)); // 2; // 2 elements before 30 in tree order
4450
+ * console.log(tree.getRank(50)); // 4; // largest → rank 4
4451
+ * console.log(tree.getRank(25)); // 2;
4452
+ */
4453
+ getRank(key: K): number {
4454
+ return this.#core.getRank(key);
4455
+ }
4456
+
4457
+ /**
4458
+ * Returns keys by rank range (0-indexed, inclusive on both ends).
4459
+ * @remarks Time O(log n + k). Requires `enableOrderStatistic: true`.
4460
+
4461
+ * @example
4462
+ * // Pagination with rangeByRank
4463
+ * const tree = new TreeMap<number>(
4464
+ * [10, 20, 30, 40, 50, 60, 70, 80, 90],
4465
+ * { enableOrderStatistic: true }
4466
+ * );
4467
+ * const pageSize = 3;
4468
+ *
4469
+ * // Page 1
4470
+ * console.log(tree.rangeByRank(0, pageSize - 1)); // [10, 20, 30];
4471
+ * // Page 2
4472
+ * console.log(tree.rangeByRank(pageSize, 2 * pageSize - 1)); // [40, 50, 60];
4473
+ * // Page 3
4474
+ * console.log(tree.rangeByRank(2 * pageSize, 3 * pageSize - 1)); // [70, 80, 90];
4475
+ */
4476
+ rangeByRank(start: number, end: number): Array<[K, V | undefined]> {
4477
+ const keys = this.#core.rangeByRank(start, end);
4478
+ return keys
4479
+ .filter((k): k is K => k !== undefined)
4480
+ .map(k => [k, this.#core.get(k)] as [K, V | undefined]);
4481
+ }
4482
+
1679
4483
  /**
1680
4484
  * Creates a shallow clone of this map.
1681
4485
  * @remarks Time O(n log n), Space O(n)
@@ -1697,6 +4501,126 @@ export class TreeMap<K = any, V = any, R = [K, V]> implements Iterable<[K, V | u
1697
4501
 
1698
4502
 
1699
4503
 
4504
+
4505
+
4506
+
4507
+
4508
+
4509
+
4510
+
4511
+
4512
+
4513
+
4514
+
4515
+
4516
+
4517
+
4518
+
4519
+
4520
+
4521
+
4522
+
4523
+
4524
+
4525
+
4526
+
4527
+
4528
+
4529
+
4530
+
4531
+
4532
+
4533
+
4534
+
4535
+
4536
+
4537
+
4538
+
4539
+
4540
+
4541
+
4542
+
4543
+
4544
+
4545
+
4546
+
4547
+
4548
+
4549
+
4550
+
4551
+
4552
+
4553
+
4554
+
4555
+
4556
+
4557
+
4558
+
4559
+
4560
+
4561
+
4562
+
4563
+
4564
+
4565
+
4566
+
4567
+
4568
+
4569
+
4570
+
4571
+
4572
+
4573
+
4574
+
4575
+
4576
+
4577
+
4578
+
4579
+
4580
+
4581
+
4582
+
4583
+
4584
+
4585
+
4586
+
4587
+
4588
+
4589
+
4590
+
4591
+
4592
+
4593
+
4594
+
4595
+
4596
+
4597
+
4598
+
4599
+
4600
+
4601
+
4602
+
4603
+
4604
+
4605
+
4606
+
4607
+
4608
+
4609
+
4610
+
4611
+
4612
+
4613
+
4614
+
4615
+
4616
+
4617
+
4618
+
4619
+
4620
+
4621
+
4622
+
4623
+
1700
4624
 
1701
4625
 
1702
4626