data-structure-typed 2.6.0 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.github/workflows/ci.yml +7 -2
  2. package/.github/workflows/release-package.yml +9 -2
  3. package/docs-site-docusaurus/docs/api/classes/AVLTree.md +108 -108
  4. package/docs-site-docusaurus/docs/api/classes/BST.md +101 -101
  5. package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +13 -13
  6. package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +66 -66
  7. package/docs-site-docusaurus/docs/api/classes/Deque.md +235 -51
  8. package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +21 -21
  9. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +231 -67
  10. package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +9 -9
  11. package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +1 -1
  12. package/docs-site-docusaurus/docs/api/classes/HashMap.md +14 -14
  13. package/docs-site-docusaurus/docs/api/classes/Heap.md +117 -34
  14. package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +83 -13
  15. package/docs-site-docusaurus/docs/api/classes/LinearBase.md +124 -20
  16. package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +140 -32
  17. package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +23 -23
  18. package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +159 -51
  19. package/docs-site-docusaurus/docs/api/classes/MapGraph.md +20 -20
  20. package/docs-site-docusaurus/docs/api/classes/Matrix.md +23 -23
  21. package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +117 -34
  22. package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +117 -34
  23. package/docs-site-docusaurus/docs/api/classes/MinHeap.md +117 -34
  24. package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +117 -34
  25. package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +117 -34
  26. package/docs-site-docusaurus/docs/api/classes/Queue.md +142 -34
  27. package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +117 -117
  28. package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +8 -8
  29. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +158 -50
  30. package/docs-site-docusaurus/docs/api/classes/SkipList.md +21 -21
  31. package/docs-site-docusaurus/docs/api/classes/Stack.md +108 -26
  32. package/docs-site-docusaurus/docs/api/classes/TreeMap.md +33 -33
  33. package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +75 -39
  34. package/docs-site-docusaurus/docs/api/classes/TreeSet.md +301 -39
  35. package/docs-site-docusaurus/docs/api/classes/Trie.md +110 -28
  36. package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +20 -20
  37. package/package.json +45 -46
  38. package/src/common/error.ts +15 -32
  39. package/src/common/index.ts +0 -3
  40. package/src/data-structures/base/iterable-element-base.ts +0 -3
  41. package/src/data-structures/base/linear-base.ts +2 -36
  42. package/src/data-structures/binary-tree/avl-tree.ts +31 -529
  43. package/src/data-structures/binary-tree/binary-indexed-tree.ts +47 -572
  44. package/src/data-structures/binary-tree/binary-tree.ts +326 -1311
  45. package/src/data-structures/binary-tree/bst.ts +158 -1082
  46. package/src/data-structures/binary-tree/red-black-tree.ts +451 -1290
  47. package/src/data-structures/binary-tree/segment-tree.ts +73 -351
  48. package/src/data-structures/binary-tree/tree-map.ts +462 -5124
  49. package/src/data-structures/binary-tree/tree-multi-map.ts +302 -4914
  50. package/src/data-structures/binary-tree/tree-multi-set.ts +284 -3972
  51. package/src/data-structures/binary-tree/tree-set.ts +338 -4836
  52. package/src/data-structures/graph/abstract-graph.ts +98 -167
  53. package/src/data-structures/graph/directed-graph.ts +137 -562
  54. package/src/data-structures/graph/map-graph.ts +0 -3
  55. package/src/data-structures/graph/undirected-graph.ts +132 -511
  56. package/src/data-structures/hash/hash-map.ts +154 -582
  57. package/src/data-structures/heap/heap.ts +200 -795
  58. package/src/data-structures/linked-list/doubly-linked-list.ts +121 -865
  59. package/src/data-structures/linked-list/singly-linked-list.ts +122 -794
  60. package/src/data-structures/linked-list/skip-linked-list.ts +211 -918
  61. package/src/data-structures/matrix/matrix.ts +179 -518
  62. package/src/data-structures/matrix/navigator.ts +0 -1
  63. package/src/data-structures/priority-queue/max-priority-queue.ts +1 -6
  64. package/src/data-structures/priority-queue/min-priority-queue.ts +6 -11
  65. package/src/data-structures/priority-queue/priority-queue.ts +1 -2
  66. package/src/data-structures/queue/deque.ts +214 -882
  67. package/src/data-structures/queue/queue.ts +102 -625
  68. package/src/data-structures/stack/stack.ts +76 -505
  69. package/src/data-structures/trie/trie.ts +98 -628
  70. package/src/types/common.ts +0 -10
  71. package/src/types/data-structures/binary-tree/bst.ts +0 -7
  72. package/src/types/data-structures/binary-tree/red-black-tree.ts +0 -1
  73. package/src/types/data-structures/graph/abstract-graph.ts +0 -2
  74. package/src/types/data-structures/hash/hash-map.ts +0 -3
  75. package/src/types/data-structures/hash/index.ts +0 -1
  76. package/src/types/data-structures/matrix/navigator.ts +0 -2
  77. package/src/types/utils/utils.ts +0 -7
  78. package/src/types/utils/validate-type.ts +0 -7
  79. package/src/utils/number.ts +0 -2
  80. package/src/utils/utils.ts +0 -5
@@ -5,7 +5,6 @@
5
5
  * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
-
9
8
  import type { ElementCallback, TrieOptions } from '../../types';
10
9
  import { IterableElementBase } from '../base';
11
10
  import { ERR, raise } from '../../common';
@@ -20,7 +19,6 @@ export class TrieNode {
20
19
  * @remarks Time O(1), Space O(1)
21
20
  * @returns New TrieNode instance.
22
21
  */
23
-
24
22
  constructor(key: string) {
25
23
  this._key = key;
26
24
  this._isEnd = false;
@@ -34,7 +32,6 @@ export class TrieNode {
34
32
  * @remarks Time O(1), Space O(1)
35
33
  * @returns Character key string.
36
34
  */
37
-
38
35
  get key(): string {
39
36
  return this._key;
40
37
  }
@@ -45,7 +42,6 @@ export class TrieNode {
45
42
  * @param value - New character key.
46
43
  * @returns void
47
44
  */
48
-
49
45
  set key(value: string) {
50
46
  this._key = value;
51
47
  }
@@ -57,7 +53,6 @@ export class TrieNode {
57
53
  * @remarks Time O(1), Space O(1)
58
54
  * @returns Map from character to child node.
59
55
  */
60
-
61
56
  get children(): Map<string, TrieNode> {
62
57
  return this._children;
63
58
  }
@@ -68,7 +63,6 @@ export class TrieNode {
68
63
  * @param value - New map of character → node.
69
64
  * @returns void
70
65
  */
71
-
72
66
  set children(value: Map<string, TrieNode>) {
73
67
  this._children = value;
74
68
  }
@@ -80,7 +74,6 @@ export class TrieNode {
80
74
  * @remarks Time O(1), Space O(1)
81
75
  * @returns True if this node ends a word.
82
76
  */
83
-
84
77
  get isEnd(): boolean {
85
78
  return this._isEnd;
86
79
  }
@@ -91,7 +84,6 @@ export class TrieNode {
91
84
  * @param value - Whether this node ends a word.
92
85
  * @returns void
93
86
  */
94
-
95
87
  set isEnd(value: boolean) {
96
88
  this._isEnd = value;
97
89
  }
@@ -221,7 +213,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
221
213
  * @param [options] - Options such as toElementFn and caseSensitive.
222
214
  * @returns New Trie instance.
223
215
  */
224
-
225
216
  constructor(words: Iterable<string> | Iterable<R> = [], options?: TrieOptions<R>) {
226
217
  super(options);
227
218
  if (options) {
@@ -240,7 +231,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
240
231
  * @remarks Time O(1), Space O(1)
241
232
  * @returns Word count.
242
233
  */
243
-
244
234
  get size(): number {
245
235
  return this._size;
246
236
  }
@@ -252,7 +242,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
252
242
  * @remarks Time O(1), Space O(1)
253
243
  * @returns True if case-sensitive.
254
244
  */
255
-
256
245
  get caseSensitive(): boolean {
257
246
  return this._caseSensitive;
258
247
  }
@@ -264,7 +253,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
264
253
  * @remarks Time O(1), Space O(1)
265
254
  * @returns Root TrieNode.
266
255
  */
267
-
268
256
  get root() {
269
257
  return this._root;
270
258
  }
@@ -274,7 +262,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
274
262
  * @remarks Time O(1), Space O(1)
275
263
  * @returns Total number of elements.
276
264
  */
277
-
278
265
  protected get _total() {
279
266
  return this._size;
280
267
  }
@@ -284,65 +271,22 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
284
271
  * @remarks Time O(L), Space O(L)
285
272
  * @param word - Word to insert.
286
273
  * @returns True if the word was newly added.
287
-
288
-
289
-
290
-
291
-
292
-
293
-
294
-
295
-
296
-
297
-
298
-
299
-
300
-
301
-
302
-
303
-
304
-
305
-
306
-
307
-
308
-
309
-
310
-
311
-
312
-
313
-
314
-
315
-
316
-
317
-
318
-
319
-
320
-
321
-
322
-
323
-
324
-
325
-
326
-
327
-
328
-
329
- * @example
330
- * // basic Trie creation and add words
331
- * // Create a simple Trie with initial words
332
- * const trie = new Trie(['apple', 'app', 'apply']);
333
- *
334
- * // Verify size
335
- * console.log(trie.size); // 3;
336
- *
337
- * // Check if words exist
338
- * console.log(trie.has('apple')); // true;
339
- * console.log(trie.has('app')); // true;
340
- *
341
- * // Add a new word
342
- * trie.add('application');
343
- * console.log(trie.size); // 4;
274
+ * @example
275
+ * // basic Trie creation and add words
276
+ * // Create a simple Trie with initial words
277
+ * const trie = new Trie(['apple', 'app', 'apply']);
278
+ *
279
+ * // Verify size
280
+ * console.log(trie.size); // 3;
281
+ *
282
+ * // Check if words exist
283
+ * console.log(trie.has('apple')); // true;
284
+ * console.log(trie.has('app')); // true;
285
+ *
286
+ * // Add a new word
287
+ * trie.add('application');
288
+ * console.log(trie.size); // 4;
344
289
  */
345
-
346
290
  add(word: string): boolean {
347
291
  word = this._caseProcess(word);
348
292
  let cur = this.root;
@@ -368,54 +312,14 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
368
312
  * @remarks Time O(ΣL), Space O(ΣL)
369
313
  * @param words - Iterable of strings (or raw records if toElementFn is provided).
370
314
  * @returns Array of per-word 'added' flags.
371
-
372
-
373
-
374
-
375
-
376
-
377
-
378
-
379
-
380
-
381
-
382
-
383
-
384
-
385
-
386
-
387
-
388
-
389
-
390
-
391
-
392
-
393
-
394
-
395
-
396
-
397
-
398
-
399
-
400
-
401
-
402
-
403
-
404
-
405
-
406
-
407
-
408
-
409
-
410
- * @example
411
- * // Add multiple words
412
- * const trie = new Trie();
413
- * trie.addMany(['cat', 'car', 'card']);
414
- * console.log(trie.has('cat')); // true;
415
- * console.log(trie.has('car')); // true;
416
- * console.log(trie.size); // 3;
315
+ * @example
316
+ * // Add multiple words
317
+ * const trie = new Trie();
318
+ * trie.addMany(['cat', 'car', 'card']);
319
+ * console.log(trie.has('cat')); // true;
320
+ * console.log(trie.has('car')); // true;
321
+ * console.log(trie.size); // 3;
417
322
  */
418
-
419
323
  addMany(words: Iterable<string> | Iterable<R>): boolean[] {
420
324
  const ans: boolean[] = [];
421
325
  for (const word of words) {
@@ -433,57 +337,14 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
433
337
  * @remarks Time O(L), Space O(1)
434
338
  * @param word - Word to search for.
435
339
  * @returns True if present.
436
-
437
-
438
-
439
-
440
-
441
-
442
-
443
-
444
-
445
-
446
-
447
-
448
-
449
-
450
-
451
-
452
-
453
-
454
-
455
-
456
-
457
-
458
-
459
-
460
-
461
-
462
-
463
-
464
-
465
-
466
-
467
-
468
-
469
-
470
-
471
-
472
-
473
-
474
-
475
-
476
-
477
-
478
- * @example
479
- * // Check if a word exists
480
- * const dict = new Trie(['apple', 'app', 'application']);
481
- *
482
- * console.log(dict.has('app')); // true;
483
- * console.log(dict.has('apple')); // true;
484
- * console.log(dict.has('ap')); // false;
340
+ * @example
341
+ * // Check if a word exists
342
+ * const dict = new Trie(['apple', 'app', 'application']);
343
+ *
344
+ * console.log(dict.has('app')); // true;
345
+ * console.log(dict.has('apple')); // true;
346
+ * console.log(dict.has('ap')); // false;
485
347
  */
486
-
487
348
  override has(word: string): boolean {
488
349
  word = this._caseProcess(word);
489
350
  let cur = this.root;
@@ -499,53 +360,13 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
499
360
  * Check whether the trie is empty.
500
361
  * @remarks Time O(1), Space O(1)
501
362
  * @returns True if size is 0.
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
- * @example
542
- * // Check if empty
543
- * const trie = new Trie();
544
- * console.log(trie.isEmpty()); // true;
545
- * trie.add('word');
546
- * console.log(trie.isEmpty()); // false;
363
+ * @example
364
+ * // Check if empty
365
+ * const trie = new Trie();
366
+ * console.log(trie.isEmpty()); // true;
367
+ * trie.add('word');
368
+ * console.log(trie.isEmpty()); // false;
547
369
  */
548
-
549
370
  isEmpty(): boolean {
550
371
  return this._size === 0;
551
372
  }
@@ -554,52 +375,12 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
554
375
  * Remove all words and reset to a fresh root.
555
376
  * @remarks Time O(1), Space O(1)
556
377
  * @returns void
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
- * @example
597
- * // Remove all words
598
- * const trie = new Trie(['a', 'b', 'c']);
599
- * trie.clear();
600
- * console.log(trie.isEmpty()); // true;
378
+ * @example
379
+ * // Remove all words
380
+ * const trie = new Trie(['a', 'b', 'c']);
381
+ * trie.clear();
382
+ * console.log(trie.isEmpty()); // true;
601
383
  */
602
-
603
384
  clear(): void {
604
385
  this._size = 0;
605
386
  this._root = new TrieNode('');
@@ -610,67 +391,24 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
610
391
  * @remarks Time O(L), Space O(1)
611
392
  * @param word - Word to delete.
612
393
  * @returns True if a word was removed.
613
-
614
-
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
- * @example
656
- * // Trie delete and iteration
657
- * const trie = new Trie(['car', 'card', 'care', 'careful', 'can', 'cat']);
658
- *
659
- * // Delete a word
660
- * trie.delete('card');
661
- * console.log(trie.has('card')); // false;
662
- *
663
- * // Word with same prefix still exists
664
- * console.log(trie.has('care')); // true;
665
- *
666
- * // Size decreased
667
- * console.log(trie.size); // 5;
668
- *
669
- * // Iterate through all words
670
- * const allWords = [...trie];
671
- * console.log(allWords.length); // 5;
394
+ * @example
395
+ * // Trie delete and iteration
396
+ * const trie = new Trie(['car', 'card', 'care', 'careful', 'can', 'cat']);
397
+ *
398
+ * // Delete a word
399
+ * trie.delete('card');
400
+ * console.log(trie.has('card')); // false;
401
+ *
402
+ * // Word with same prefix still exists
403
+ * console.log(trie.has('care')); // true;
404
+ *
405
+ * // Size decreased
406
+ * console.log(trie.size); // 5;
407
+ *
408
+ * // Iterate through all words
409
+ * const allWords = [...trie];
410
+ * console.log(allWords.length); // 5;
672
411
  */
673
-
674
412
  delete(word: string): boolean {
675
413
  word = this._caseProcess(word);
676
414
  let isDeleted = false;
@@ -699,7 +437,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
699
437
  }
700
438
  return false;
701
439
  };
702
-
703
440
  dfs(this.root, 0);
704
441
  if (isDeleted) {
705
442
  this._size--;
@@ -712,7 +449,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
712
449
  * @remarks Time O(N), Space O(H)
713
450
  * @returns Maximum depth from root to a leaf.
714
451
  */
715
-
716
452
  getHeight(): number {
717
453
  const startNode = this.root;
718
454
  let maxDepth = 0;
@@ -739,7 +475,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
739
475
  * @param input - String to test as prefix.
740
476
  * @returns True if input is a prefix but not a full word.
741
477
  */
742
-
743
478
  hasPurePrefix(input: string): boolean {
744
479
  input = this._caseProcess(input);
745
480
  let cur = this.root;
@@ -756,57 +491,14 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
756
491
  * @remarks Time O(L), Space O(1)
757
492
  * @param input - String to test as prefix.
758
493
  * @returns True if input matches a path from root.
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
-
786
-
787
-
788
-
789
-
790
-
791
-
792
-
793
-
794
-
795
-
796
-
797
-
798
-
799
-
800
-
801
- * @example
802
- * // Check if a prefix exists
803
- * const trie = new Trie(['hello', 'help', 'world']);
804
- *
805
- * console.log(trie.hasPrefix('hel')); // true;
806
- * console.log(trie.hasPrefix('wor')); // true;
807
- * console.log(trie.hasPrefix('xyz')); // false;
494
+ * @example
495
+ * // Check if a prefix exists
496
+ * const trie = new Trie(['hello', 'help', 'world']);
497
+ *
498
+ * console.log(trie.hasPrefix('hel')); // true;
499
+ * console.log(trie.hasPrefix('wor')); // true;
500
+ * console.log(trie.hasPrefix('xyz')); // false;
808
501
  */
809
-
810
502
  hasPrefix(input: string): boolean {
811
503
  input = this._caseProcess(input);
812
504
  let cur = this.root;
@@ -824,7 +516,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
824
516
  * @param input - Candidate longest common prefix.
825
517
  * @returns True if input equals the common prefix.
826
518
  */
827
-
828
519
  hasCommonPrefix(input: string): boolean {
829
520
  input = this._caseProcess(input);
830
521
  let commonPre = '';
@@ -843,55 +534,12 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
843
534
  * Return the longest common prefix among all words.
844
535
  * @remarks Time O(H), Space O(1)
845
536
  * @returns The longest common prefix string.
846
-
847
-
848
-
849
-
850
-
851
-
852
-
853
-
854
-
855
-
856
-
857
-
858
-
859
-
860
-
861
-
862
-
863
-
864
-
865
-
866
-
867
-
868
-
869
-
870
-
871
-
872
-
873
-
874
-
875
-
876
-
877
-
878
-
879
-
880
-
881
-
882
-
883
-
884
-
885
-
886
-
887
-
888
- * @example
889
- * // Find shared prefix
890
- * const trie = new Trie(['flower', 'flow', 'flight']);
891
- *
892
- * console.log(trie.getLongestCommonPrefix()); // 'fl';
537
+ * @example
538
+ * // Find shared prefix
539
+ * const trie = new Trie(['flower', 'flow', 'flight']);
540
+ *
541
+ * console.log(trie.getLongestCommonPrefix()); // 'fl';
893
542
  */
894
-
895
543
  getLongestCommonPrefix(): string {
896
544
  let commonPre = '';
897
545
  const dfs = (cur: TrieNode) => {
@@ -911,66 +559,22 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
911
559
  * @param [max] - Maximum number of words to return; default is Number.MAX_SAFE_INTEGER.
912
560
  * @param [isAllWhenEmptyPrefix] - When true, collect from root even if prefix is empty.
913
561
  * @returns Array of collected words (at most max).
914
-
915
-
916
-
917
-
918
-
919
-
920
-
921
-
922
-
923
-
924
-
925
-
926
-
927
-
928
-
929
-
930
-
931
-
932
-
933
-
934
-
935
-
936
-
937
-
938
-
939
-
940
-
941
-
942
-
943
-
944
-
945
-
946
-
947
-
948
-
949
-
950
-
951
-
952
-
953
-
954
-
955
-
956
- * @example
957
- * // Trie getWords and prefix search
958
- * const trie = new Trie(['apple', 'app', 'apply', 'application', 'apricot']);
959
- *
960
- * // Get all words with prefix 'app'
961
- * const appWords = trie.getWords('app');
962
- * console.log(appWords); // contains 'app';
963
- * console.log(appWords); // contains 'apple';
964
- * console.log(appWords); // contains 'apply';
965
- * console.log(appWords); // contains 'application';
966
- * expect(appWords).not.toContain('apricot');
562
+ * @example
563
+ * // Trie getWords and prefix search
564
+ * const trie = new Trie(['apple', 'app', 'apply', 'application', 'apricot']);
565
+ *
566
+ * // Get all words with prefix 'app'
567
+ * const appWords = trie.getWords('app');
568
+ * console.log(appWords); // contains 'app';
569
+ * console.log(appWords); // contains 'apple';
570
+ * console.log(appWords); // contains 'apply';
571
+ * console.log(appWords); // contains 'application';
572
+ * expect(appWords).not.toContain('apricot');
967
573
  */
968
-
969
574
  getWords(prefix = '', max = Number.MAX_SAFE_INTEGER, isAllWhenEmptyPrefix = false): string[] {
970
575
  prefix = this._caseProcess(prefix);
971
576
  const words: string[] = [];
972
577
  let found = 0;
973
-
974
578
  const dfs = (node: TrieNode, word: string): void => {
975
579
  for (const [char, childNode] of node.children) {
976
580
  if (found >= max) return;
@@ -982,9 +586,7 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
982
586
  found++;
983
587
  }
984
588
  };
985
-
986
589
  let startNode = this.root;
987
-
988
590
  if (prefix) {
989
591
  for (const c of prefix) {
990
592
  const nodeC = startNode.children.get(c);
@@ -995,9 +597,7 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
995
597
  }
996
598
  }
997
599
  }
998
-
999
600
  if (isAllWhenEmptyPrefix || startNode !== this.root) dfs(startNode, prefix);
1000
-
1001
601
  return words;
1002
602
  }
1003
603
 
@@ -1005,53 +605,13 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
1005
605
  * Deep clone this trie by iterating and inserting all words.
1006
606
  * @remarks Time O(ΣL), Space O(ΣL)
1007
607
  * @returns A new trie with the same words and options.
1008
-
1009
-
1010
-
1011
-
1012
-
1013
-
1014
-
1015
-
1016
-
1017
-
1018
-
1019
-
1020
-
1021
-
1022
-
1023
-
1024
-
1025
-
1026
-
1027
-
1028
-
1029
-
1030
-
1031
-
1032
-
1033
-
1034
-
1035
-
1036
-
1037
-
1038
-
1039
-
1040
-
1041
-
1042
-
1043
-
1044
-
1045
-
1046
-
1047
- * @example
1048
- * // Create independent copy
1049
- * const trie = new Trie(['hello', 'world']);
1050
- * const copy = trie.clone();
1051
- * copy.delete('hello');
1052
- * console.log(trie.has('hello')); // true;
608
+ * @example
609
+ * // Create independent copy
610
+ * const trie = new Trie(['hello', 'world']);
611
+ * const copy = trie.clone();
612
+ * copy.delete('hello');
613
+ * console.log(trie.has('hello')); // true;
1053
614
  */
1054
-
1055
615
  clone(): this {
1056
616
  const next = this._createInstance();
1057
617
  for (const x of this) next.add(x);
@@ -1064,52 +624,12 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
1064
624
  * @param predicate - Predicate (word, index, trie) → boolean to keep word.
1065
625
  * @param [thisArg] - Value for `this` inside the predicate.
1066
626
  * @returns A new trie containing words that satisfy the predicate.
1067
-
1068
-
1069
-
1070
-
1071
-
1072
-
1073
-
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
- * @example
1107
- * // Filter words
1108
- * const trie = new Trie(['cat', 'car', 'dog', 'card']);
1109
- * const result = trie.filter(w => w.startsWith('ca'));
1110
- * console.log(result.size); // 3;
627
+ * @example
628
+ * // Filter words
629
+ * const trie = new Trie(['cat', 'car', 'dog', 'card']);
630
+ * const result = trie.filter(w => w.startsWith('ca'));
631
+ * console.log(result.size); // 3;
1111
632
  */
1112
-
1113
633
  filter(predicate: ElementCallback<string, R, boolean>, thisArg?: unknown): this {
1114
634
  const results = this._createInstance();
1115
635
  let index = 0;
@@ -1122,52 +642,13 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
1122
642
  return results;
1123
643
  }
1124
644
 
1125
- /**
645
+ /**
1126
646
  * Transform words
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
- * @example
1167
- * // Transform words
1168
- * const trie = new Trie(['hello', 'world']);
1169
- * const upper = trie.map(w => w.toUpperCase());
1170
- * console.log(upper.has('HELLO')); // true;
647
+ * @example
648
+ * // Transform words
649
+ * const trie = new Trie(['hello', 'world']);
650
+ * const upper = trie.map(w => w.toUpperCase());
651
+ * console.log(upper.has('HELLO')); // true;
1171
652
  */
1172
653
  map<RM>(callback: ElementCallback<string, R, string>, options?: TrieOptions<RM>, thisArg?: unknown): Trie<RM>;
1173
654
 
@@ -1181,13 +662,11 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
1181
662
  * @param [thisArg] - Value for `this` inside the callback.
1182
663
  * @returns A new Trie constructed from mapped words.
1183
664
  */
1184
-
1185
665
  map<EM, RM>(
1186
666
  callback: ElementCallback<string, R, EM>,
1187
667
  options?: TrieOptions<RM>,
1188
668
  thisArg?: unknown
1189
669
  ): IterableElementBase<EM, RM>;
1190
-
1191
670
  map<EM, RM>(callback: ElementCallback<string, R, EM>, options?: TrieOptions<RM>, thisArg?: unknown): any {
1192
671
  const newTrie = this._createLike<RM>([], options);
1193
672
  let i = 0;
@@ -1208,7 +687,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
1208
687
  * @param [thisArg] - Value for `this` inside the callback.
1209
688
  * @returns A new trie with mapped words.
1210
689
  */
1211
-
1212
690
  mapSame(callback: ElementCallback<string, R, string>, thisArg?: unknown): this {
1213
691
  const next = this._createInstance();
1214
692
  let i = 0;
@@ -1225,12 +703,8 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
1225
703
  * @param [options] - Options forwarded to the constructor.
1226
704
  * @returns An empty like-kind trie instance.
1227
705
  */
1228
-
1229
706
  protected _createInstance(options?: TrieOptions<R>): this {
1230
- const Ctor = this.constructor as new (
1231
- elements?: Iterable<string> | Iterable<R>,
1232
- options?: TrieOptions<R>
1233
- ) => this;
707
+ const Ctor = this.constructor as new (elements?: Iterable<string> | Iterable<R>, options?: TrieOptions<R>) => this;
1234
708
  return new Ctor([], {
1235
709
  toElementFn: this.toElementFn,
1236
710
  caseSensitive: this.caseSensitive,
@@ -1246,7 +720,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
1246
720
  * @param [options] - Options forwarded to the constructor.
1247
721
  * @returns A like-kind Trie instance.
1248
722
  */
1249
-
1250
723
  protected _createLike<RM>(elements: Iterable<string> | Iterable<RM> = [], options?: TrieOptions<RM>): Trie<RM> {
1251
724
  const Ctor = this.constructor as new (
1252
725
  elements?: Iterable<string> | Iterable<RM>,
@@ -1262,7 +735,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
1262
735
  * @param [options] - Options forwarded to the constructor.
1263
736
  * @returns An empty like-kind Trie instance.
1264
737
  */
1265
-
1266
738
  protected _spawnLike<RM>(options?: TrieOptions<RM>): Trie<RM> {
1267
739
  return this._createLike<RM>([], options);
1268
740
  }
@@ -1272,7 +744,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
1272
744
  * @remarks Time O(ΣL), Space O(H)
1273
745
  * @returns Iterator of words.
1274
746
  */
1275
-
1276
747
  protected *_getIterator(): IterableIterator<string> {
1277
748
  function* _dfs(node: TrieNode, path: string): IterableIterator<string> {
1278
749
  if (node.isEnd) {
@@ -1292,7 +763,6 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
1292
763
  * @param str - Input string to normalize.
1293
764
  * @returns Normalized string based on caseSensitive.
1294
765
  */
1295
-
1296
766
  protected _caseProcess(str: string) {
1297
767
  if (!this._caseSensitive) {
1298
768
  str = str.toLowerCase();