data-structure-typed 2.4.4 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -1
- package/README.md +34 -1
- package/dist/cjs/index.cjs +10639 -2151
- package/dist/cjs-legacy/index.cjs +10694 -2195
- package/dist/esm/index.mjs +10639 -2150
- package/dist/esm-legacy/index.mjs +10694 -2194
- package/dist/types/common/error.d.ts +23 -0
- package/dist/types/common/index.d.ts +1 -0
- 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 +439 -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 +217 -31
- 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/abstract-graph.d.ts +44 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -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 +313 -66
- 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/types/types/data-structures/queue/deque.d.ts +6 -0
- package/dist/umd/data-structure-typed.js +10725 -2221
- package/dist/umd/data-structure-typed.min.js +4 -2
- package/package.json +5 -4
- package/src/common/error.ts +60 -0
- package/src/common/index.ts +2 -0
- package/src/data-structures/base/iterable-element-base.ts +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +146 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +317 -247
- package/src/data-structures/binary-tree/binary-tree.ts +567 -121
- package/src/data-structures/binary-tree/bst.ts +370 -37
- package/src/data-structures/binary-tree/red-black-tree.ts +328 -96
- package/src/data-structures/binary-tree/segment-tree.ts +378 -248
- package/src/data-structures/binary-tree/tree-map.ts +1411 -13
- package/src/data-structures/binary-tree/tree-multi-map.ts +1218 -215
- package/src/data-structures/binary-tree/tree-multi-set.ts +959 -69
- package/src/data-structures/binary-tree/tree-set.ts +1257 -15
- package/src/data-structures/graph/abstract-graph.ts +106 -1
- package/src/data-structures/graph/directed-graph.ts +233 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +308 -59
- package/src/data-structures/hash/hash-map.ts +254 -79
- package/src/data-structures/heap/heap.ts +305 -102
- package/src/data-structures/heap/max-heap.ts +48 -3
- 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 +433 -22
- package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
- 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 +358 -68
- 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 +227 -44
- 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
- package/src/types/data-structures/queue/deque.ts +7 -0
- package/src/utils/utils.ts +4 -2
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import type { Comparator } from '../../types';
|
|
11
11
|
import type { TreeSetElementCallback, TreeSetOptions, TreeSetRangeOptions, TreeSetReduceCallback } from '../../types';
|
|
12
|
+
import { ERR } from '../../common';
|
|
12
13
|
import { RedBlackTree } from './red-black-tree';
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -16,6 +17,11 @@ import { RedBlackTree } from './red-black-tree';
|
|
|
16
17
|
*
|
|
17
18
|
* - Iteration order is ascending by key.
|
|
18
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;
|
|
19
25
|
*/
|
|
20
26
|
export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
21
27
|
readonly #core: RedBlackTree<K, undefined>;
|
|
@@ -66,27 +72,26 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
66
72
|
return (a: K, b: K): number => {
|
|
67
73
|
// numbers
|
|
68
74
|
if (typeof a === 'number' && typeof b === 'number') {
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
/* istanbul ignore next -- _validateKey prevents NaN from entering the tree */
|
|
76
|
+
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN('TreeSet'));
|
|
71
77
|
const aa = Object.is(a, -0) ? 0 : a;
|
|
72
78
|
const bb = Object.is(b, -0) ? 0 : b;
|
|
73
79
|
return aa > bb ? 1 : aa < bb ? -1 : 0;
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
// strings
|
|
77
82
|
if (typeof a === 'string' && typeof b === 'string') {
|
|
78
83
|
return a > b ? 1 : a < b ? -1 : 0;
|
|
79
84
|
}
|
|
80
85
|
|
|
81
|
-
// Date
|
|
82
86
|
if (a instanceof Date && b instanceof Date) {
|
|
83
87
|
const ta = a.getTime();
|
|
84
88
|
const tb = b.getTime();
|
|
85
|
-
|
|
89
|
+
/* istanbul ignore next -- _validateKey prevents invalid Date from entering the tree */
|
|
90
|
+
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate('TreeSet'));
|
|
86
91
|
return ta > tb ? 1 : ta < tb ? -1 : 0;
|
|
87
92
|
}
|
|
88
93
|
|
|
89
|
-
throw new TypeError('TreeSet
|
|
94
|
+
throw new TypeError(ERR.comparatorRequired('TreeSet'));
|
|
90
95
|
};
|
|
91
96
|
}
|
|
92
97
|
|
|
@@ -99,6 +104,52 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
99
104
|
|
|
100
105
|
/**
|
|
101
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;
|
|
102
153
|
*/
|
|
103
154
|
isEmpty(): boolean {
|
|
104
155
|
return this.size === 0;
|
|
@@ -108,24 +159,81 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
108
159
|
if (!this.#isDefaultComparator) return;
|
|
109
160
|
|
|
110
161
|
if (typeof key === 'number') {
|
|
111
|
-
if (Number.isNaN(key)) throw new TypeError('TreeSet
|
|
162
|
+
if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN('TreeSet'));
|
|
112
163
|
return;
|
|
113
164
|
}
|
|
114
165
|
|
|
115
166
|
if (typeof key === 'string') return;
|
|
116
167
|
|
|
117
168
|
if (key instanceof Date) {
|
|
118
|
-
if (Number.isNaN(key.getTime())) throw new TypeError('TreeSet
|
|
169
|
+
if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate('TreeSet'));
|
|
119
170
|
return;
|
|
120
171
|
}
|
|
121
172
|
|
|
122
173
|
// Other key types should have provided a comparator, so reaching here means misuse.
|
|
123
|
-
throw new TypeError('TreeSet
|
|
174
|
+
throw new TypeError(ERR.comparatorRequired('TreeSet'));
|
|
124
175
|
}
|
|
125
176
|
|
|
126
177
|
/**
|
|
127
178
|
* Add a key to the set (no-op if already present).
|
|
128
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';
|
|
129
237
|
*/
|
|
130
238
|
add(key: K): this {
|
|
131
239
|
this._validateKey(key);
|
|
@@ -137,6 +245,66 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
137
245
|
/**
|
|
138
246
|
* Test whether a key exists.
|
|
139
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;
|
|
140
308
|
*/
|
|
141
309
|
has(key: K): boolean {
|
|
142
310
|
this._validateKey(key);
|
|
@@ -147,6 +315,67 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
147
315
|
* Delete a key.
|
|
148
316
|
* @returns `true` if the key existed; otherwise `false`.
|
|
149
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];
|
|
150
379
|
*/
|
|
151
380
|
delete(key: K): boolean {
|
|
152
381
|
this._validateKey(key);
|
|
@@ -156,6 +385,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
156
385
|
|
|
157
386
|
/**
|
|
158
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;
|
|
159
436
|
*/
|
|
160
437
|
clear(): void {
|
|
161
438
|
this.#core.clear();
|
|
@@ -163,6 +440,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
163
440
|
|
|
164
441
|
/**
|
|
165
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];
|
|
166
490
|
*/
|
|
167
491
|
keys(): IterableIterator<K> {
|
|
168
492
|
return this.#core.keys();
|
|
@@ -172,6 +496,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
172
496
|
* Iterate over values in ascending order.
|
|
173
497
|
*
|
|
174
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];
|
|
175
546
|
*/
|
|
176
547
|
values(): IterableIterator<K> {
|
|
177
548
|
return this.keys();
|
|
@@ -181,6 +552,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
181
552
|
* Iterate over `[value, value]` pairs (native Set convention).
|
|
182
553
|
*
|
|
183
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];
|
|
184
602
|
*/
|
|
185
603
|
*entries(): IterableIterator<[K, K]> {
|
|
186
604
|
for (const k of this.keys()) yield [k, k];
|
|
@@ -194,6 +612,55 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
194
612
|
* Visit each value in ascending order.
|
|
195
613
|
*
|
|
196
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];
|
|
197
664
|
*/
|
|
198
665
|
forEach(cb: (value: K, value2: K, set: TreeSet<K>) => void, thisArg?: any): void {
|
|
199
666
|
for (const k of this) cb.call(thisArg, k, k, this);
|
|
@@ -204,6 +671,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
204
671
|
*
|
|
205
672
|
* This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
|
|
206
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];
|
|
207
722
|
*/
|
|
208
723
|
map<MK>(
|
|
209
724
|
callbackfn: TreeSetElementCallback<K, MK, TreeSet<K>>,
|
|
@@ -224,6 +739,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
224
739
|
/**
|
|
225
740
|
* Create a new TreeSet containing only values that satisfy the predicate.
|
|
226
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];
|
|
227
790
|
*/
|
|
228
791
|
filter(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): TreeSet<K> {
|
|
229
792
|
const out = new TreeSet<K>([], { comparator: this.#userComparator });
|
|
@@ -240,6 +803,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
240
803
|
/**
|
|
241
804
|
* Reduce values into a single accumulator.
|
|
242
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;
|
|
243
854
|
*/
|
|
244
855
|
reduce<A>(callbackfn: TreeSetReduceCallback<K, A, TreeSet<K>>, initialValue: A): A {
|
|
245
856
|
let acc = initialValue;
|
|
@@ -251,6 +862,51 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
251
862
|
/**
|
|
252
863
|
* Test whether all values satisfy a predicate.
|
|
253
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;
|
|
254
910
|
*/
|
|
255
911
|
every(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
|
|
256
912
|
let index = 0;
|
|
@@ -266,6 +922,51 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
266
922
|
/**
|
|
267
923
|
* Test whether any value satisfies a predicate.
|
|
268
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;
|
|
269
970
|
*/
|
|
270
971
|
some(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
|
|
271
972
|
let index = 0;
|
|
@@ -281,6 +982,52 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
281
982
|
/**
|
|
282
983
|
* Find the first value that satisfies a predicate.
|
|
283
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;
|
|
284
1031
|
*/
|
|
285
1032
|
find(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): K | undefined {
|
|
286
1033
|
let index = 0;
|
|
@@ -296,6 +1043,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
296
1043
|
/**
|
|
297
1044
|
* Materialize the set into an array of keys.
|
|
298
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];
|
|
299
1093
|
*/
|
|
300
1094
|
toArray(): K[] {
|
|
301
1095
|
return [...this];
|
|
@@ -304,6 +1098,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
304
1098
|
/**
|
|
305
1099
|
* Print a human-friendly representation.
|
|
306
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();
|
|
307
1148
|
*/
|
|
308
1149
|
print(): void {
|
|
309
1150
|
// Delegate to the underlying tree's visualization.
|
|
@@ -314,6 +1155,45 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
314
1155
|
|
|
315
1156
|
/**
|
|
316
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'];
|
|
317
1197
|
*/
|
|
318
1198
|
first(): K | undefined {
|
|
319
1199
|
return this.#core.getLeftMost();
|
|
@@ -321,6 +1201,23 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
321
1201
|
|
|
322
1202
|
/**
|
|
323
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;
|
|
324
1221
|
*/
|
|
325
1222
|
last(): K | undefined {
|
|
326
1223
|
return this.#core.getRightMost();
|
|
@@ -328,6 +1225,25 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
328
1225
|
|
|
329
1226
|
/**
|
|
330
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;
|
|
331
1247
|
*/
|
|
332
1248
|
pollFirst(): K | undefined {
|
|
333
1249
|
const k = this.first();
|
|
@@ -338,6 +1254,24 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
338
1254
|
|
|
339
1255
|
/**
|
|
340
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;
|
|
341
1275
|
*/
|
|
342
1276
|
pollLast(): K | undefined {
|
|
343
1277
|
const k = this.last();
|
|
@@ -348,6 +1282,64 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
348
1282
|
|
|
349
1283
|
/**
|
|
350
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;
|
|
351
1343
|
*/
|
|
352
1344
|
ceiling(key: K): K | undefined {
|
|
353
1345
|
this._validateKey(key);
|
|
@@ -356,6 +1348,56 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
356
1348
|
|
|
357
1349
|
/**
|
|
358
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;
|
|
359
1401
|
*/
|
|
360
1402
|
floor(key: K): K | undefined {
|
|
361
1403
|
this._validateKey(key);
|
|
@@ -364,6 +1406,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
364
1406
|
|
|
365
1407
|
/**
|
|
366
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;
|
|
367
1457
|
*/
|
|
368
1458
|
higher(key: K): K | undefined {
|
|
369
1459
|
this._validateKey(key);
|
|
@@ -372,6 +1462,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
372
1462
|
|
|
373
1463
|
/**
|
|
374
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;
|
|
375
1513
|
*/
|
|
376
1514
|
lower(key: K): K | undefined {
|
|
377
1515
|
this._validateKey(key);
|
|
@@ -383,6 +1521,65 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
383
1521
|
*
|
|
384
1522
|
* @param range `[low, high]`
|
|
385
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;
|
|
386
1583
|
*/
|
|
387
1584
|
rangeSearch(range: [K, K], options: TreeSetRangeOptions = {}): K[] {
|
|
388
1585
|
const { lowInclusive = true, highInclusive = true } = options;
|
|
@@ -396,7 +1593,7 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
396
1593
|
const cmp = this.#core.comparator;
|
|
397
1594
|
|
|
398
1595
|
for (const k of keys) {
|
|
399
|
-
if (k === undefined) continue;
|
|
1596
|
+
/* istanbul ignore next -- defensive: tree keys are never undefined */ if (k === undefined) continue;
|
|
400
1597
|
if (!lowInclusive && cmp(k, low) === 0) continue;
|
|
401
1598
|
if (!highInclusive && cmp(k, high) === 0) continue;
|
|
402
1599
|
out.push(k);
|
|
@@ -408,11 +1605,56 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
408
1605
|
/**
|
|
409
1606
|
* Creates a shallow clone of this set.
|
|
410
1607
|
* @remarks Time O(n log n), Space O(n)
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
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;
|
|
416
1658
|
*/
|
|
417
1659
|
clone(): TreeSet<K> {
|
|
418
1660
|
return new TreeSet<K>(this, {
|