data-structure-typed 2.4.5 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +15 -5
- package/dist/cjs/index.cjs +10240 -2079
- package/dist/cjs-legacy/index.cjs +10305 -2135
- package/dist/esm/index.mjs +10241 -2078
- package/dist/esm-legacy/index.mjs +10306 -2134
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +429 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +212 -32
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/directed-graph.d.ts +219 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +204 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +272 -65
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/umd/data-structure-typed.js +10308 -2133
- package/dist/umd/data-structure-typed.min.js +4 -4
- package/package.json +5 -4
- package/src/data-structures/base/iterable-element-base.ts +4 -5
- package/src/data-structures/binary-tree/avl-tree.ts +146 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +316 -247
- package/src/data-structures/binary-tree/binary-tree.ts +454 -79
- package/src/data-structures/binary-tree/bst.ts +359 -34
- package/src/data-structures/binary-tree/red-black-tree.ts +309 -97
- package/src/data-structures/binary-tree/segment-tree.ts +378 -248
- package/src/data-structures/binary-tree/tree-map.ts +1403 -6
- package/src/data-structures/binary-tree/tree-multi-map.ts +1214 -211
- package/src/data-structures/binary-tree/tree-multi-set.ts +954 -65
- package/src/data-structures/binary-tree/tree-set.ts +1250 -9
- package/src/data-structures/graph/directed-graph.ts +229 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +213 -59
- package/src/data-structures/hash/hash-map.ts +241 -77
- package/src/data-structures/heap/heap.ts +301 -99
- package/src/data-structures/heap/max-heap.ts +46 -0
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +303 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +293 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +707 -90
- package/src/data-structures/matrix/matrix.ts +424 -12
- package/src/data-structures/priority-queue/max-priority-queue.ts +57 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +287 -65
- package/src/data-structures/queue/queue.ts +223 -42
- package/src/data-structures/stack/stack.ts +184 -32
- package/src/data-structures/trie/trie.ts +225 -43
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
|
@@ -17,6 +17,11 @@ import { RedBlackTree } from './red-black-tree';
|
|
|
17
17
|
*
|
|
18
18
|
* - Iteration order is ascending by key.
|
|
19
19
|
* - No node exposure: all APIs use keys only.
|
|
20
|
+
* @example
|
|
21
|
+
* // Set multiple key-value pairs
|
|
22
|
+
* const ts = new TreeSet<number, string>();
|
|
23
|
+
* ts.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
24
|
+
* console.log(ts.size); // 3;
|
|
20
25
|
*/
|
|
21
26
|
export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
22
27
|
readonly #core: RedBlackTree<K, undefined>;
|
|
@@ -67,22 +72,21 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
67
72
|
return (a: K, b: K): number => {
|
|
68
73
|
// numbers
|
|
69
74
|
if (typeof a === 'number' && typeof b === 'number') {
|
|
75
|
+
/* istanbul ignore next -- _validateKey prevents NaN from entering the tree */
|
|
70
76
|
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN('TreeSet'));
|
|
71
|
-
// treat -0 and 0 as equal
|
|
72
77
|
const aa = Object.is(a, -0) ? 0 : a;
|
|
73
78
|
const bb = Object.is(b, -0) ? 0 : b;
|
|
74
79
|
return aa > bb ? 1 : aa < bb ? -1 : 0;
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
// strings
|
|
78
82
|
if (typeof a === 'string' && typeof b === 'string') {
|
|
79
83
|
return a > b ? 1 : a < b ? -1 : 0;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
|
-
// Date
|
|
83
86
|
if (a instanceof Date && b instanceof Date) {
|
|
84
87
|
const ta = a.getTime();
|
|
85
88
|
const tb = b.getTime();
|
|
89
|
+
/* istanbul ignore next -- _validateKey prevents invalid Date from entering the tree */
|
|
86
90
|
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate('TreeSet'));
|
|
87
91
|
return ta > tb ? 1 : ta < tb ? -1 : 0;
|
|
88
92
|
}
|
|
@@ -100,6 +104,52 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
100
104
|
|
|
101
105
|
/**
|
|
102
106
|
* Whether the set is empty.
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
* @example
|
|
151
|
+
* // Check empty
|
|
152
|
+
* console.log(new TreeSet().isEmpty()); // true;
|
|
103
153
|
*/
|
|
104
154
|
isEmpty(): boolean {
|
|
105
155
|
return this.size === 0;
|
|
@@ -127,6 +177,63 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
127
177
|
/**
|
|
128
178
|
* Add a key to the set (no-op if already present).
|
|
129
179
|
* @remarks Expected time O(log n)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
* @example
|
|
227
|
+
* // Unique tags with sorted order
|
|
228
|
+
* const tags = new TreeSet<string>(['javascript', 'typescript', 'react', 'typescript', 'node']);
|
|
229
|
+
*
|
|
230
|
+
* // Duplicates removed, sorted alphabetically
|
|
231
|
+
* console.log([...tags]); // ['javascript', 'node', 'react', 'typescript'];
|
|
232
|
+
* console.log(tags.size); // 4;
|
|
233
|
+
*
|
|
234
|
+
* tags.add('angular');
|
|
235
|
+
* console.log(tags.first()); // 'angular';
|
|
236
|
+
* console.log(tags.last()); // 'typescript';
|
|
130
237
|
*/
|
|
131
238
|
add(key: K): this {
|
|
132
239
|
this._validateKey(key);
|
|
@@ -138,6 +245,66 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
138
245
|
/**
|
|
139
246
|
* Test whether a key exists.
|
|
140
247
|
* @remarks Expected time O(log n)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
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
|
+
* @example
|
|
303
|
+
* // Checking membership in a sorted collection
|
|
304
|
+
* const allowed = new TreeSet<string>(['admin', 'editor', 'viewer']);
|
|
305
|
+
*
|
|
306
|
+
* console.log(allowed.has('admin')); // true;
|
|
307
|
+
* console.log(allowed.has('guest')); // false;
|
|
141
308
|
*/
|
|
142
309
|
has(key: K): boolean {
|
|
143
310
|
this._validateKey(key);
|
|
@@ -148,6 +315,67 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
148
315
|
* Delete a key.
|
|
149
316
|
* @returns `true` if the key existed; otherwise `false`.
|
|
150
317
|
* @remarks Expected time O(log n)
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
* @example
|
|
373
|
+
* // Removing elements while maintaining order
|
|
374
|
+
* const nums = new TreeSet<number>([1, 3, 5, 7, 9]);
|
|
375
|
+
*
|
|
376
|
+
* console.log(nums.delete(5)); // true;
|
|
377
|
+
* console.log(nums.delete(5)); // false; // already gone
|
|
378
|
+
* console.log([...nums]); // [1, 3, 7, 9];
|
|
151
379
|
*/
|
|
152
380
|
delete(key: K): boolean {
|
|
153
381
|
this._validateKey(key);
|
|
@@ -157,6 +385,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
157
385
|
|
|
158
386
|
/**
|
|
159
387
|
* Remove all keys.
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
* @example
|
|
432
|
+
* // Remove all
|
|
433
|
+
* const ts = new TreeSet<number>([1, 2]);
|
|
434
|
+
* ts.clear();
|
|
435
|
+
* console.log(ts.isEmpty()); // true;
|
|
160
436
|
*/
|
|
161
437
|
clear(): void {
|
|
162
438
|
this.#core.clear();
|
|
@@ -164,6 +440,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
164
440
|
|
|
165
441
|
/**
|
|
166
442
|
* Iterate over keys in ascending order.
|
|
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
|
+
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
* @example
|
|
487
|
+
* // Get sorted keys
|
|
488
|
+
* const ts = new TreeSet<number>([30, 10, 20]);
|
|
489
|
+
* console.log([...ts.keys()]); // [10, 20, 30];
|
|
167
490
|
*/
|
|
168
491
|
keys(): IterableIterator<K> {
|
|
169
492
|
return this.#core.keys();
|
|
@@ -173,6 +496,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
173
496
|
* Iterate over values in ascending order.
|
|
174
497
|
*
|
|
175
498
|
* Note: for Set-like containers, `values()` is the same as `keys()`.
|
|
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
|
+
* // Get values (same as keys for Set)
|
|
544
|
+
* const ts = new TreeSet<number>([2, 1, 3]);
|
|
545
|
+
* console.log([...ts.values()]); // [1, 2, 3];
|
|
176
546
|
*/
|
|
177
547
|
values(): IterableIterator<K> {
|
|
178
548
|
return this.keys();
|
|
@@ -182,6 +552,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
182
552
|
* Iterate over `[value, value]` pairs (native Set convention).
|
|
183
553
|
*
|
|
184
554
|
* Note: TreeSet stores only keys internally; `[k, k]` is created on-the-fly during iteration.
|
|
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
|
+
|
|
598
|
+
* @example
|
|
599
|
+
* // Iterate entries
|
|
600
|
+
* const ts = new TreeSet<number>([3, 1, 2]);
|
|
601
|
+
* console.log([...ts.entries()].map(([k]) => k)); // [1, 2, 3];
|
|
185
602
|
*/
|
|
186
603
|
*entries(): IterableIterator<[K, K]> {
|
|
187
604
|
for (const k of this.keys()) yield [k, k];
|
|
@@ -195,6 +612,55 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
195
612
|
* Visit each value in ascending order.
|
|
196
613
|
*
|
|
197
614
|
* Callback follows native Set convention: `(value, value2, set)`.
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
* @example
|
|
659
|
+
* // Execute for each
|
|
660
|
+
* const ts = new TreeSet<number>([3, 1, 2]);
|
|
661
|
+
* const keys: number[] = [];
|
|
662
|
+
* ts.forEach(k => keys.push(k));
|
|
663
|
+
* console.log(keys); // [1, 2, 3];
|
|
198
664
|
*/
|
|
199
665
|
forEach(cb: (value: K, value2: K, set: TreeSet<K>) => void, thisArg?: any): void {
|
|
200
666
|
for (const k of this) cb.call(thisArg, k, k, this);
|
|
@@ -205,6 +671,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
205
671
|
*
|
|
206
672
|
* This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
|
|
207
673
|
* @remarks Time O(n log n) expected, Space O(n)
|
|
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
|
+
|
|
716
|
+
|
|
717
|
+
* @example
|
|
718
|
+
* // Transform
|
|
719
|
+
* const ts = new TreeSet<number>([1, 2, 3]);
|
|
720
|
+
* const doubled = ts.map(k => k * 2);
|
|
721
|
+
* console.log([...doubled]); // [2, 4, 6];
|
|
208
722
|
*/
|
|
209
723
|
map<MK>(
|
|
210
724
|
callbackfn: TreeSetElementCallback<K, MK, TreeSet<K>>,
|
|
@@ -225,6 +739,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
225
739
|
/**
|
|
226
740
|
* Create a new TreeSet containing only values that satisfy the predicate.
|
|
227
741
|
* @remarks Time O(n log n) expected, Space O(n)
|
|
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
|
+
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
* @example
|
|
786
|
+
* // Filter
|
|
787
|
+
* const ts = new TreeSet<number>([1, 2, 3, 4, 5]);
|
|
788
|
+
* const evens = ts.filter(k => k % 2 === 0);
|
|
789
|
+
* console.log([...evens]); // [2, 4];
|
|
228
790
|
*/
|
|
229
791
|
filter(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): TreeSet<K> {
|
|
230
792
|
const out = new TreeSet<K>([], { comparator: this.#userComparator });
|
|
@@ -241,6 +803,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
241
803
|
/**
|
|
242
804
|
* Reduce values into a single accumulator.
|
|
243
805
|
* @remarks Time O(n), Space O(1)
|
|
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
|
+
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
* @example
|
|
850
|
+
* // Aggregate
|
|
851
|
+
* const ts = new TreeSet<number>([1, 2, 3]);
|
|
852
|
+
* const sum = ts.reduce((acc, k) => acc + k, 0);
|
|
853
|
+
* console.log(sum); // 6;
|
|
244
854
|
*/
|
|
245
855
|
reduce<A>(callbackfn: TreeSetReduceCallback<K, A, TreeSet<K>>, initialValue: A): A {
|
|
246
856
|
let acc = initialValue;
|
|
@@ -252,6 +862,51 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
252
862
|
/**
|
|
253
863
|
* Test whether all values satisfy a predicate.
|
|
254
864
|
* @remarks Time O(n), Space O(1)
|
|
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
|
+
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
* @example
|
|
907
|
+
* // Test all
|
|
908
|
+
* const ts = new TreeSet<number>([2, 4, 6]);
|
|
909
|
+
* console.log(ts.every(k => k > 0)); // true;
|
|
255
910
|
*/
|
|
256
911
|
every(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
|
|
257
912
|
let index = 0;
|
|
@@ -267,6 +922,51 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
267
922
|
/**
|
|
268
923
|
* Test whether any value satisfies a predicate.
|
|
269
924
|
* @remarks Time O(n), Space O(1)
|
|
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
|
+
* // Test any
|
|
968
|
+
* const ts = new TreeSet<number>([1, 3, 5]);
|
|
969
|
+
* console.log(ts.some(k => k === 3)); // true;
|
|
270
970
|
*/
|
|
271
971
|
some(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
|
|
272
972
|
let index = 0;
|
|
@@ -282,6 +982,52 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
282
982
|
/**
|
|
283
983
|
* Find the first value that satisfies a predicate.
|
|
284
984
|
* @remarks Time O(n), Space O(1)
|
|
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
|
+
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
* @example
|
|
1027
|
+
* // Find entry
|
|
1028
|
+
* const ts = new TreeSet<number>([1, 2, 3]);
|
|
1029
|
+
* const found = ts.find(k => k === 2);
|
|
1030
|
+
* console.log(found); // 2;
|
|
285
1031
|
*/
|
|
286
1032
|
find(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): K | undefined {
|
|
287
1033
|
let index = 0;
|
|
@@ -297,6 +1043,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
297
1043
|
/**
|
|
298
1044
|
* Materialize the set into an array of keys.
|
|
299
1045
|
* @remarks Time O(n), Space O(n)
|
|
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
|
+
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
* @example
|
|
1090
|
+
* // Convert to array
|
|
1091
|
+
* const ts = new TreeSet<number>([3, 1, 2]);
|
|
1092
|
+
* console.log(ts.toArray()); // [1, 2, 3];
|
|
300
1093
|
*/
|
|
301
1094
|
toArray(): K[] {
|
|
302
1095
|
return [...this];
|
|
@@ -305,6 +1098,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
305
1098
|
/**
|
|
306
1099
|
* Print a human-friendly representation.
|
|
307
1100
|
* @remarks Time O(n), Space O(n)
|
|
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
|
+
* @example
|
|
1145
|
+
* // Display tree
|
|
1146
|
+
* const ts = new TreeSet<number>([1, 2, 3]);
|
|
1147
|
+
* expect(() => ts.print()).not.toThrow();
|
|
308
1148
|
*/
|
|
309
1149
|
print(): void {
|
|
310
1150
|
// Delegate to the underlying tree's visualization.
|
|
@@ -315,6 +1155,45 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
315
1155
|
|
|
316
1156
|
/**
|
|
317
1157
|
* Smallest key in the set.
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
* @example
|
|
1171
|
+
* // Student grade ranking with custom comparator
|
|
1172
|
+
* interface Student {
|
|
1173
|
+
* name: string;
|
|
1174
|
+
* gpa: number;
|
|
1175
|
+
* }
|
|
1176
|
+
*
|
|
1177
|
+
* const ranking = new TreeSet<Student>(
|
|
1178
|
+
* [
|
|
1179
|
+
* { name: 'Alice', gpa: 3.8 },
|
|
1180
|
+
* { name: 'Bob', gpa: 3.5 },
|
|
1181
|
+
* { name: 'Charlie', gpa: 3.9 },
|
|
1182
|
+
* { name: 'Diana', gpa: 3.5 }
|
|
1183
|
+
* ],
|
|
1184
|
+
* { comparator: (a, b) => b.gpa - a.gpa || a.name.localeCompare(b.name) }
|
|
1185
|
+
* );
|
|
1186
|
+
*
|
|
1187
|
+
* // Sorted by GPA descending, then name ascending
|
|
1188
|
+
* const names = [...ranking].map(s => s.name);
|
|
1189
|
+
* console.log(names); // ['Charlie', 'Alice', 'Bob', 'Diana'];
|
|
1190
|
+
*
|
|
1191
|
+
* // Top student
|
|
1192
|
+
* console.log(ranking.first()?.name); // 'Charlie';
|
|
1193
|
+
*
|
|
1194
|
+
* // Filter students with GPA >= 3.8
|
|
1195
|
+
* const honors = ranking.filter(s => s.gpa >= 3.8);
|
|
1196
|
+
* console.log(honors.toArray().map(s => s.name)); // ['Charlie', 'Alice'];
|
|
318
1197
|
*/
|
|
319
1198
|
first(): K | undefined {
|
|
320
1199
|
return this.#core.getLeftMost();
|
|
@@ -322,6 +1201,23 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
322
1201
|
|
|
323
1202
|
/**
|
|
324
1203
|
* Largest key in the set.
|
|
1204
|
+
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
* @example
|
|
1217
|
+
* // Get the maximum element
|
|
1218
|
+
* const temps = new TreeSet<number>([18, 22, 15, 30, 25]);
|
|
1219
|
+
* console.log(temps.last()); // 30;
|
|
1220
|
+
* console.log(temps.first()); // 15;
|
|
325
1221
|
*/
|
|
326
1222
|
last(): K | undefined {
|
|
327
1223
|
return this.#core.getRightMost();
|
|
@@ -329,6 +1225,25 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
329
1225
|
|
|
330
1226
|
/**
|
|
331
1227
|
* Remove and return the smallest key.
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
|
|
1238
|
+
|
|
1239
|
+
|
|
1240
|
+
* @example
|
|
1241
|
+
* // Remove and return minimum
|
|
1242
|
+
* const queue = new TreeSet<number>([5, 1, 8, 3]);
|
|
1243
|
+
*
|
|
1244
|
+
* console.log(queue.pollFirst()); // 1;
|
|
1245
|
+
* console.log(queue.pollFirst()); // 3;
|
|
1246
|
+
* console.log(queue.size); // 2;
|
|
332
1247
|
*/
|
|
333
1248
|
pollFirst(): K | undefined {
|
|
334
1249
|
const k = this.first();
|
|
@@ -339,6 +1254,24 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
339
1254
|
|
|
340
1255
|
/**
|
|
341
1256
|
* Remove and return the largest key.
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
* @example
|
|
1270
|
+
* // Remove and return maximum
|
|
1271
|
+
* const stack = new TreeSet<number>([10, 20, 30]);
|
|
1272
|
+
*
|
|
1273
|
+
* console.log(stack.pollLast()); // 30;
|
|
1274
|
+
* console.log(stack.size); // 2;
|
|
342
1275
|
*/
|
|
343
1276
|
pollLast(): K | undefined {
|
|
344
1277
|
const k = this.last();
|
|
@@ -349,6 +1282,64 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
349
1282
|
|
|
350
1283
|
/**
|
|
351
1284
|
* Smallest key that is >= the given key.
|
|
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
|
+
* @example
|
|
1328
|
+
* // Finding nearest available time slot
|
|
1329
|
+
* // Available appointment times (minutes from midnight)
|
|
1330
|
+
* const slots = new TreeSet<number>([540, 600, 660, 720, 840, 900]);
|
|
1331
|
+
*
|
|
1332
|
+
* // Customer wants something around 10:30 (630 min)
|
|
1333
|
+
* const nearest = slots.ceiling(630);
|
|
1334
|
+
* console.log(nearest); // 660; // 11:00 AM
|
|
1335
|
+
*
|
|
1336
|
+
* // What's the latest slot before 2:00 PM (840)?
|
|
1337
|
+
* const before2pm = slots.lower(840);
|
|
1338
|
+
* console.log(before2pm); // 720; // 12:00 PM
|
|
1339
|
+
*
|
|
1340
|
+
* // Book the 11:00 slot
|
|
1341
|
+
* slots.delete(660);
|
|
1342
|
+
* console.log(slots.ceiling(630)); // 720;
|
|
352
1343
|
*/
|
|
353
1344
|
ceiling(key: K): K | undefined {
|
|
354
1345
|
this._validateKey(key);
|
|
@@ -357,6 +1348,56 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
357
1348
|
|
|
358
1349
|
/**
|
|
359
1350
|
* Largest key that is <= the given key.
|
|
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
|
+
* @example
|
|
1394
|
+
* // Largest element ≤ target
|
|
1395
|
+
* const breakpoints = new TreeSet<number>([320, 768, 1024, 1280, 1920]);
|
|
1396
|
+
*
|
|
1397
|
+
* // Current width is 800 → which breakpoint applies?
|
|
1398
|
+
* console.log(breakpoints.floor(800)); // 768;
|
|
1399
|
+
* console.log(breakpoints.floor(1024)); // 1024; // exact match
|
|
1400
|
+
* console.log(breakpoints.floor(100)); // undefined;
|
|
360
1401
|
*/
|
|
361
1402
|
floor(key: K): K | undefined {
|
|
362
1403
|
this._validateKey(key);
|
|
@@ -365,6 +1406,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
365
1406
|
|
|
366
1407
|
/**
|
|
367
1408
|
* Smallest key that is > the given key.
|
|
1409
|
+
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
|
|
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
|
+
* @example
|
|
1452
|
+
* // Smallest element strictly > target
|
|
1453
|
+
* const levels = new TreeSet<number>([1, 5, 10, 25, 50, 100]);
|
|
1454
|
+
*
|
|
1455
|
+
* console.log(levels.higher(10)); // 25;
|
|
1456
|
+
* console.log(levels.higher(100)); // undefined;
|
|
368
1457
|
*/
|
|
369
1458
|
higher(key: K): K | undefined {
|
|
370
1459
|
this._validateKey(key);
|
|
@@ -373,6 +1462,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
373
1462
|
|
|
374
1463
|
/**
|
|
375
1464
|
* Largest key that is < the given key.
|
|
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
|
+
* @example
|
|
1508
|
+
* // Largest element strictly < target
|
|
1509
|
+
* const tiers = new TreeSet<number>([100, 200, 500, 1000]);
|
|
1510
|
+
*
|
|
1511
|
+
* console.log(tiers.lower(500)); // 200;
|
|
1512
|
+
* console.log(tiers.lower(100)); // undefined;
|
|
376
1513
|
*/
|
|
377
1514
|
lower(key: K): K | undefined {
|
|
378
1515
|
this._validateKey(key);
|
|
@@ -384,6 +1521,65 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
384
1521
|
*
|
|
385
1522
|
* @param range `[low, high]`
|
|
386
1523
|
* @param options Inclusive/exclusive bounds (defaults to inclusive).
|
|
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
|
+
* @example
|
|
1567
|
+
* // IP address blocklist with range checking
|
|
1568
|
+
* // Simplified: use numeric IP representation
|
|
1569
|
+
* const blocklist = new TreeSet<number>([
|
|
1570
|
+
* 167772160, // 10.0.0.0
|
|
1571
|
+
* 167772416, // 10.0.1.0
|
|
1572
|
+
* 167772672, // 10.0.2.0
|
|
1573
|
+
* 167773184 // 10.0.4.0
|
|
1574
|
+
* ]);
|
|
1575
|
+
*
|
|
1576
|
+
* // Check if any blocked IP is in range 10.0.1.0 - 10.0.3.0
|
|
1577
|
+
* const inRange = blocklist.rangeSearch([167772416, 167772928]);
|
|
1578
|
+
* console.log(inRange); // [167772416, 167772672];
|
|
1579
|
+
*
|
|
1580
|
+
* // Quick membership check
|
|
1581
|
+
* console.log(blocklist.has(167772416)); // true;
|
|
1582
|
+
* console.log(blocklist.has(167772800)); // false;
|
|
387
1583
|
*/
|
|
388
1584
|
rangeSearch(range: [K, K], options: TreeSetRangeOptions = {}): K[] {
|
|
389
1585
|
const { lowInclusive = true, highInclusive = true } = options;
|
|
@@ -397,7 +1593,7 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
397
1593
|
const cmp = this.#core.comparator;
|
|
398
1594
|
|
|
399
1595
|
for (const k of keys) {
|
|
400
|
-
if (k === undefined) continue;
|
|
1596
|
+
/* istanbul ignore next -- defensive: tree keys are never undefined */ if (k === undefined) continue;
|
|
401
1597
|
if (!lowInclusive && cmp(k, low) === 0) continue;
|
|
402
1598
|
if (!highInclusive && cmp(k, high) === 0) continue;
|
|
403
1599
|
out.push(k);
|
|
@@ -409,11 +1605,56 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
409
1605
|
/**
|
|
410
1606
|
* Creates a shallow clone of this set.
|
|
411
1607
|
* @remarks Time O(n log n), Space O(n)
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
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
|
+
* @example
|
|
1653
|
+
* // Deep clone
|
|
1654
|
+
* const ts = new TreeSet<number>([1, 2, 3]);
|
|
1655
|
+
* const copy = ts.clone();
|
|
1656
|
+
* copy.delete(1);
|
|
1657
|
+
* console.log(ts.has(1)); // true;
|
|
417
1658
|
*/
|
|
418
1659
|
clone(): TreeSet<K> {
|
|
419
1660
|
return new TreeSet<K>(this, {
|