data-structure-typed 2.4.3 → 2.4.5
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/.github/workflows/release.yml +27 -0
- package/CHANGELOG.md +24 -1
- package/README.md +70 -51
- package/dist/cjs/index.cjs +486 -167
- package/dist/cjs-legacy/index.cjs +487 -165
- package/dist/esm/index.mjs +486 -168
- package/dist/esm-legacy/index.mjs +487 -166
- 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/binary-tree.d.ts +15 -5
- package/dist/types/data-structures/binary-tree/bst.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +7 -1
- package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +3 -2
- package/dist/types/data-structures/graph/undirected-graph.d.ts +16 -2
- package/dist/types/data-structures/hash/hash-map.d.ts +2 -2
- package/dist/types/data-structures/heap/heap.d.ts +3 -7
- package/dist/types/data-structures/queue/deque.d.ts +41 -1
- package/dist/types/types/data-structures/binary-tree/avl-tree.d.ts +1 -1
- package/dist/types/types/data-structures/binary-tree/red-black-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/doubly-linked-list.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/singly-linked-list.d.ts +1 -1
- package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -1
- package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
- package/dist/types/types/data-structures/stack/stack.d.ts +1 -1
- package/dist/umd/data-structure-typed.js +486 -164
- package/dist/umd/data-structure-typed.min.js +6 -4
- package/package.json +2 -2
- package/src/common/error.ts +60 -0
- package/src/common/index.ts +2 -0
- package/src/data-structures/base/iterable-element-base.ts +5 -4
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +6 -5
- package/src/data-structures/binary-tree/binary-tree.ts +121 -49
- package/src/data-structures/binary-tree/bst.ts +12 -4
- package/src/data-structures/binary-tree/red-black-tree.ts +20 -0
- package/src/data-structures/binary-tree/tree-map.ts +8 -7
- package/src/data-structures/binary-tree/tree-multi-map.ts +4 -4
- package/src/data-structures/binary-tree/tree-multi-set.ts +10 -9
- package/src/data-structures/binary-tree/tree-set.ts +7 -6
- package/src/data-structures/graph/abstract-graph.ts +124 -19
- package/src/data-structures/graph/directed-graph.ts +8 -4
- package/src/data-structures/graph/map-graph.ts +1 -1
- package/src/data-structures/graph/undirected-graph.ts +99 -4
- package/src/data-structures/hash/hash-map.ts +19 -6
- package/src/data-structures/heap/heap.ts +21 -17
- package/src/data-structures/heap/max-heap.ts +2 -3
- package/src/data-structures/linked-list/doubly-linked-list.ts +4 -4
- package/src/data-structures/linked-list/singly-linked-list.ts +15 -9
- package/src/data-structures/matrix/matrix.ts +9 -10
- package/src/data-structures/priority-queue/max-priority-queue.ts +2 -3
- package/src/data-structures/queue/deque.ts +72 -4
- package/src/data-structures/stack/stack.ts +1 -1
- package/src/data-structures/trie/trie.ts +12 -6
- package/src/types/data-structures/binary-tree/avl-tree.ts +1 -1
- package/src/types/data-structures/binary-tree/red-black-tree.ts +1 -1
- package/src/types/data-structures/linked-list/doubly-linked-list.ts +1 -1
- package/src/types/data-structures/linked-list/singly-linked-list.ts +1 -1
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -1
- package/src/types/data-structures/queue/deque.ts +7 -0
- package/src/types/data-structures/stack/stack.ts +1 -1
- package/src/utils/utils.ts +4 -2
|
@@ -182,7 +182,7 @@ export class DoublyLinkedListNode<E = any> extends LinkedListNode<E> {
|
|
|
182
182
|
* console.log(foundEntry?.value); // 'Bob';
|
|
183
183
|
*/
|
|
184
184
|
export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, DoublyLinkedListNode<E>> {
|
|
185
|
-
protected _equals: (a: E, b: E) => boolean = Object.is
|
|
185
|
+
protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
|
|
186
186
|
|
|
187
187
|
/**
|
|
188
188
|
* Create a DoublyLinkedList and optionally bulk-insert elements.
|
|
@@ -423,8 +423,8 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
|
|
|
423
423
|
at(index: number): E | undefined {
|
|
424
424
|
if (index < 0 || index >= this._length) return undefined;
|
|
425
425
|
let current = this.head;
|
|
426
|
-
for (let i = 0; i < index; i++) current = current
|
|
427
|
-
return current
|
|
426
|
+
for (let i = 0; i < index && current; i++) current = current.next;
|
|
427
|
+
return current?.value;
|
|
428
428
|
}
|
|
429
429
|
|
|
430
430
|
/**
|
|
@@ -437,7 +437,7 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
|
|
|
437
437
|
getNodeAt(index: number): DoublyLinkedListNode<E> | undefined {
|
|
438
438
|
if (index < 0 || index >= this._length) return undefined;
|
|
439
439
|
let current = this.head;
|
|
440
|
-
for (let i = 0; i < index; i++) current = current
|
|
440
|
+
for (let i = 0; i < index && current; i++) current = current.next;
|
|
441
441
|
return current;
|
|
442
442
|
}
|
|
443
443
|
|
|
@@ -246,7 +246,7 @@ export class SinglyLinkedListNode<E = any> extends LinkedListNode<E> {
|
|
|
246
246
|
* console.log(editor.getText()); // 'Haello';
|
|
247
247
|
*/
|
|
248
248
|
export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, SinglyLinkedListNode<E>> {
|
|
249
|
-
protected _equals: (a: E, b: E) => boolean = Object.is
|
|
249
|
+
protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
|
|
250
250
|
|
|
251
251
|
/**
|
|
252
252
|
* Create a SinglyLinkedList and optionally bulk-insert elements.
|
|
@@ -381,8 +381,8 @@ export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, S
|
|
|
381
381
|
return value;
|
|
382
382
|
}
|
|
383
383
|
let current = this.head;
|
|
384
|
-
while (current.next !== this.tail) current = current.next
|
|
385
|
-
const value = this.tail
|
|
384
|
+
while (current.next && current.next !== this.tail) current = current.next;
|
|
385
|
+
const value = this.tail?.value;
|
|
386
386
|
current.next = undefined;
|
|
387
387
|
this._tail = current;
|
|
388
388
|
this._length--;
|
|
@@ -484,8 +484,8 @@ export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, S
|
|
|
484
484
|
at(index: number): E | undefined {
|
|
485
485
|
if (index < 0 || index >= this._length) return undefined;
|
|
486
486
|
let current = this.head;
|
|
487
|
-
for (let i = 0; i < index; i++) current = current
|
|
488
|
-
return current
|
|
487
|
+
for (let i = 0; i < index && current; i++) current = current.next;
|
|
488
|
+
return current?.value;
|
|
489
489
|
}
|
|
490
490
|
|
|
491
491
|
/**
|
|
@@ -511,7 +511,7 @@ export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, S
|
|
|
511
511
|
getNodeAt(index: number): SinglyLinkedListNode<E> | undefined {
|
|
512
512
|
if (index < 0 || index >= this._length) return undefined;
|
|
513
513
|
let current = this.head;
|
|
514
|
-
for (let i = 0; i < index; i++) current = current
|
|
514
|
+
for (let i = 0; i < index && current; i++) current = current.next;
|
|
515
515
|
return current;
|
|
516
516
|
}
|
|
517
517
|
|
|
@@ -1003,7 +1003,10 @@ export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, S
|
|
|
1003
1003
|
*/
|
|
1004
1004
|
|
|
1005
1005
|
protected _createInstance(options?: SinglyLinkedListOptions<E, R>): this {
|
|
1006
|
-
const Ctor
|
|
1006
|
+
const Ctor = this.constructor as new (
|
|
1007
|
+
elements?: Iterable<E> | Iterable<R> | Iterable<SinglyLinkedListNode<E>>,
|
|
1008
|
+
options?: SinglyLinkedListOptions<E, R>
|
|
1009
|
+
) => this;
|
|
1007
1010
|
return new Ctor([], options);
|
|
1008
1011
|
}
|
|
1009
1012
|
|
|
@@ -1021,8 +1024,11 @@ export class SinglyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, S
|
|
|
1021
1024
|
elements: Iterable<EM> | Iterable<RM> | Iterable<SinglyLinkedListNode<EM>> = [],
|
|
1022
1025
|
options?: SinglyLinkedListOptions<EM, RM>
|
|
1023
1026
|
): SinglyLinkedList<EM, RM> {
|
|
1024
|
-
const Ctor
|
|
1025
|
-
|
|
1027
|
+
const Ctor = this.constructor as new (
|
|
1028
|
+
elements?: Iterable<EM> | Iterable<RM> | Iterable<SinglyLinkedListNode<EM>>,
|
|
1029
|
+
options?: SinglyLinkedListOptions<EM, RM>
|
|
1030
|
+
) => SinglyLinkedList<EM, RM>;
|
|
1031
|
+
return new Ctor(elements, options);
|
|
1026
1032
|
}
|
|
1027
1033
|
|
|
1028
1034
|
/**
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
import type { MatrixOptions } from '../../types';
|
|
9
|
+
import { ERR } from '../../common';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
*
|
|
@@ -150,7 +151,7 @@ export class Matrix {
|
|
|
150
151
|
*/
|
|
151
152
|
add(matrix: Matrix): Matrix | undefined {
|
|
152
153
|
if (!this.isMatchForCalculate(matrix)) {
|
|
153
|
-
throw new Error('
|
|
154
|
+
throw new Error(ERR.matrixDimensionMismatch('addition'));
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
const resultData: number[][] = [];
|
|
@@ -186,7 +187,7 @@ export class Matrix {
|
|
|
186
187
|
*/
|
|
187
188
|
subtract(matrix: Matrix): Matrix | undefined {
|
|
188
189
|
if (!this.isMatchForCalculate(matrix)) {
|
|
189
|
-
throw new Error('
|
|
190
|
+
throw new Error(ERR.matrixDimensionMismatch('subtraction'));
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
const resultData: number[][] = [];
|
|
@@ -221,7 +222,7 @@ export class Matrix {
|
|
|
221
222
|
*/
|
|
222
223
|
multiply(matrix: Matrix): Matrix | undefined {
|
|
223
224
|
if (this.cols !== matrix.rows) {
|
|
224
|
-
throw new Error('
|
|
225
|
+
throw new Error(ERR.matrixDimensionMismatch('multiplication (A.cols must equal B.rows)'));
|
|
225
226
|
}
|
|
226
227
|
|
|
227
228
|
const resultData: number[][] = [];
|
|
@@ -259,7 +260,7 @@ export class Matrix {
|
|
|
259
260
|
*/
|
|
260
261
|
transpose(): Matrix {
|
|
261
262
|
if (this.data.some(row => row.length !== this.rows)) {
|
|
262
|
-
throw new Error(
|
|
263
|
+
throw new Error(ERR.matrixNotRectangular());
|
|
263
264
|
}
|
|
264
265
|
|
|
265
266
|
const resultData: number[][] = [];
|
|
@@ -288,7 +289,7 @@ export class Matrix {
|
|
|
288
289
|
inverse(): Matrix | undefined {
|
|
289
290
|
// Check if the matrix is square
|
|
290
291
|
if (this.rows !== this.cols) {
|
|
291
|
-
throw new Error(
|
|
292
|
+
throw new Error(ERR.matrixNotSquare());
|
|
292
293
|
}
|
|
293
294
|
|
|
294
295
|
// Create an augmented matrix [this | I]
|
|
@@ -318,7 +319,7 @@ export class Matrix {
|
|
|
318
319
|
|
|
319
320
|
if (pivotRow === this.rows) {
|
|
320
321
|
// Matrix is singular, and its inverse does not exist
|
|
321
|
-
throw new Error(
|
|
322
|
+
throw new Error(ERR.matrixSingular());
|
|
322
323
|
}
|
|
323
324
|
|
|
324
325
|
// Swap rows to make the pivot the current row
|
|
@@ -329,7 +330,7 @@ export class Matrix {
|
|
|
329
330
|
|
|
330
331
|
if (pivotElement === 0) {
|
|
331
332
|
// Handle division by zero
|
|
332
|
-
throw new Error(
|
|
333
|
+
throw new Error(ERR.matrixSingular());
|
|
333
334
|
}
|
|
334
335
|
|
|
335
336
|
augmentedMatrix._scaleRow(i, 1 / pivotElement);
|
|
@@ -367,9 +368,7 @@ export class Matrix {
|
|
|
367
368
|
*/
|
|
368
369
|
dot(matrix: Matrix): Matrix | undefined {
|
|
369
370
|
if (this.cols !== matrix.rows) {
|
|
370
|
-
throw new Error(
|
|
371
|
-
'Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product.'
|
|
372
|
-
);
|
|
371
|
+
throw new Error(ERR.matrixDimensionMismatch('dot product (A.cols must equal B.rows)'));
|
|
373
372
|
}
|
|
374
373
|
|
|
375
374
|
const resultData: number[][] = [];
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { PriorityQueueOptions } from '../../types';
|
|
9
9
|
import { PriorityQueue } from './priority-queue';
|
|
10
|
+
import { ERR } from '../../common';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Max-oriented priority queue (max-heap) built on {@link PriorityQueue}.
|
|
@@ -28,9 +29,7 @@ export class MaxPriorityQueue<E = any, R = any> extends PriorityQueue<E, R> {
|
|
|
28
29
|
super(elements, {
|
|
29
30
|
comparator: (a: E, b: E): number => {
|
|
30
31
|
if (typeof a === 'object' || typeof b === 'object') {
|
|
31
|
-
throw TypeError(
|
|
32
|
-
`When comparing object types, a custom comparator must be defined in the constructor's options parameter.`
|
|
33
|
-
);
|
|
32
|
+
throw new TypeError(ERR.comparatorRequired('MaxPriorityQueue'));
|
|
34
33
|
}
|
|
35
34
|
if (a < b) return 1;
|
|
36
35
|
if (a > b) return -1;
|
|
@@ -144,7 +144,7 @@ import { LinearBase } from '../base/linear-base';
|
|
|
144
144
|
* console.log(dataWindow.length); // 3;
|
|
145
145
|
*/
|
|
146
146
|
export class Deque<E = any, R = any> extends LinearBase<E, R> {
|
|
147
|
-
protected _equals: (a: E, b: E) => boolean = Object.is
|
|
147
|
+
protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
|
|
148
148
|
|
|
149
149
|
/**
|
|
150
150
|
* Create a Deque and optionally bulk-insert elements.
|
|
@@ -154,12 +154,15 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
|
|
|
154
154
|
* @returns New Deque instance.
|
|
155
155
|
*/
|
|
156
156
|
|
|
157
|
+
constructor(elements?: IterableWithSizeOrLength<E>, options?: DequeOptions<E, R>);
|
|
158
|
+
constructor(elements: IterableWithSizeOrLength<R>, options: DequeOptions<E, R> & { toElementFn: (rawElement: R) => E });
|
|
157
159
|
constructor(elements: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R> = [], options?: DequeOptions<E, R>) {
|
|
158
160
|
super(options);
|
|
159
161
|
|
|
160
162
|
if (options) {
|
|
161
|
-
const { bucketSize } = options;
|
|
163
|
+
const { bucketSize, autoCompactRatio } = options;
|
|
162
164
|
if (typeof bucketSize === 'number') this._bucketSize = bucketSize;
|
|
165
|
+
if (typeof autoCompactRatio === 'number') this._autoCompactRatio = autoCompactRatio;
|
|
163
166
|
}
|
|
164
167
|
|
|
165
168
|
let _size: number;
|
|
@@ -191,6 +194,34 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
|
|
|
191
194
|
return this._bucketSize;
|
|
192
195
|
}
|
|
193
196
|
|
|
197
|
+
protected _autoCompactRatio = 0.5;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Get the auto-compaction ratio.
|
|
201
|
+
* When `elements / (bucketCount * bucketSize)` drops below this ratio after
|
|
202
|
+
* enough shift/pop operations, the deque auto-compacts.
|
|
203
|
+
* @remarks Time O(1), Space O(1)
|
|
204
|
+
* @returns Current ratio threshold. 0 means auto-compact is disabled.
|
|
205
|
+
*/
|
|
206
|
+
get autoCompactRatio(): number {
|
|
207
|
+
return this._autoCompactRatio;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Set the auto-compaction ratio.
|
|
212
|
+
* @remarks Time O(1), Space O(1)
|
|
213
|
+
* @param value - Ratio in [0,1]. 0 disables auto-compact.
|
|
214
|
+
*/
|
|
215
|
+
set autoCompactRatio(value: number) {
|
|
216
|
+
this._autoCompactRatio = value;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Counter for shift/pop operations since last compaction check.
|
|
221
|
+
* Only checks ratio every `_bucketSize` operations to minimize overhead.
|
|
222
|
+
*/
|
|
223
|
+
protected _compactCounter = 0;
|
|
224
|
+
|
|
194
225
|
protected _bucketFirst = 0;
|
|
195
226
|
|
|
196
227
|
/**
|
|
@@ -366,6 +397,7 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
|
|
|
366
397
|
}
|
|
367
398
|
}
|
|
368
399
|
this._length -= 1;
|
|
400
|
+
this._autoCompact();
|
|
369
401
|
return element;
|
|
370
402
|
}
|
|
371
403
|
|
|
@@ -390,6 +422,7 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
|
|
|
390
422
|
}
|
|
391
423
|
}
|
|
392
424
|
this._length -= 1;
|
|
425
|
+
this._autoCompact();
|
|
393
426
|
return element;
|
|
394
427
|
}
|
|
395
428
|
|
|
@@ -768,11 +801,44 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
|
|
|
768
801
|
* @returns void
|
|
769
802
|
*/
|
|
770
803
|
|
|
804
|
+
/**
|
|
805
|
+
* (Protected) Trigger auto-compaction if space utilization drops below threshold.
|
|
806
|
+
* Only checks every `_bucketSize` operations to minimize hot-path overhead.
|
|
807
|
+
* Uses element-based ratio: `elements / (bucketCount * bucketSize)`.
|
|
808
|
+
*/
|
|
809
|
+
protected _autoCompact(): void {
|
|
810
|
+
if (this._autoCompactRatio <= 0 || this._bucketCount <= 1) return;
|
|
811
|
+
|
|
812
|
+
this._compactCounter++;
|
|
813
|
+
if (this._compactCounter < this._bucketSize) return;
|
|
814
|
+
this._compactCounter = 0;
|
|
815
|
+
|
|
816
|
+
const utilization = this._length / (this._bucketCount * this._bucketSize);
|
|
817
|
+
if (utilization < this._autoCompactRatio) {
|
|
818
|
+
this.shrinkToFit();
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Compact the deque by removing unused buckets.
|
|
824
|
+
* @remarks Time O(N), Space O(1)
|
|
825
|
+
* @returns True if compaction was performed (bucket count reduced).
|
|
826
|
+
*/
|
|
827
|
+
/**
|
|
828
|
+
* Compact the deque by removing unused buckets.
|
|
829
|
+
* @remarks Time O(N), Space O(1)
|
|
830
|
+
* @returns True if compaction was performed (bucket count reduced).
|
|
831
|
+
*/
|
|
832
|
+
compact(): boolean {
|
|
833
|
+
const before = this._bucketCount;
|
|
834
|
+
this.shrinkToFit();
|
|
835
|
+
return this._bucketCount < before;
|
|
836
|
+
}
|
|
837
|
+
|
|
771
838
|
shrinkToFit(): void {
|
|
772
839
|
if (this._length === 0) return;
|
|
773
840
|
const newBuckets = [] as E[][];
|
|
774
|
-
if (this._bucketFirst
|
|
775
|
-
else if (this._bucketFirst < this._bucketLast) {
|
|
841
|
+
if (this._bucketFirst <= this._bucketLast) {
|
|
776
842
|
for (let i = this._bucketFirst; i <= this._bucketLast; ++i) {
|
|
777
843
|
newBuckets.push(this._buckets[i]);
|
|
778
844
|
}
|
|
@@ -787,6 +853,8 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
|
|
|
787
853
|
this._bucketFirst = 0;
|
|
788
854
|
this._bucketLast = newBuckets.length - 1;
|
|
789
855
|
this._buckets = newBuckets;
|
|
856
|
+
this._bucketCount = newBuckets.length;
|
|
857
|
+
this._compactCounter = 0;
|
|
790
858
|
}
|
|
791
859
|
|
|
792
860
|
/**
|
|
@@ -161,7 +161,7 @@ import { IterableElementBase } from '../base';
|
|
|
161
161
|
* console.log(stack.elements.join('/')); // 'c';
|
|
162
162
|
*/
|
|
163
163
|
export class Stack<E = any, R = any> extends IterableElementBase<E, R> {
|
|
164
|
-
protected _equals: (a: E, b: E) => boolean = Object.is
|
|
164
|
+
protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
|
|
165
165
|
|
|
166
166
|
/**
|
|
167
167
|
* Create a Stack and optionally bulk-push elements.
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import type { ElementCallback, TrieOptions } from '../../types';
|
|
10
10
|
import { IterableElementBase } from '../base';
|
|
11
|
+
import { ERR } from '../../common';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Node used by Trie to store one character and its children.
|
|
@@ -651,7 +652,7 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
651
652
|
for (const x of this) {
|
|
652
653
|
const v = thisArg === undefined ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
|
|
653
654
|
if (typeof v !== 'string') {
|
|
654
|
-
throw new TypeError(
|
|
655
|
+
throw new TypeError(ERR.callbackReturnType('string', typeof v, 'Trie.map'));
|
|
655
656
|
}
|
|
656
657
|
newTrie.add(v);
|
|
657
658
|
}
|
|
@@ -684,13 +685,15 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
684
685
|
*/
|
|
685
686
|
|
|
686
687
|
protected _createInstance(options?: TrieOptions<R>): this {
|
|
687
|
-
const Ctor
|
|
688
|
-
|
|
688
|
+
const Ctor = this.constructor as new (
|
|
689
|
+
elements?: Iterable<string> | Iterable<R>,
|
|
690
|
+
options?: TrieOptions<R>
|
|
691
|
+
) => this;
|
|
692
|
+
return new Ctor([], {
|
|
689
693
|
toElementFn: this.toElementFn,
|
|
690
694
|
caseSensitive: this.caseSensitive,
|
|
691
695
|
...(options ?? {})
|
|
692
696
|
});
|
|
693
|
-
return next as this;
|
|
694
697
|
}
|
|
695
698
|
|
|
696
699
|
/**
|
|
@@ -703,8 +706,11 @@ export class Trie<R = any> extends IterableElementBase<string, R> {
|
|
|
703
706
|
*/
|
|
704
707
|
|
|
705
708
|
protected _createLike<RM>(elements: Iterable<string> | Iterable<RM> = [], options?: TrieOptions<RM>): Trie<RM> {
|
|
706
|
-
const Ctor
|
|
707
|
-
|
|
709
|
+
const Ctor = this.constructor as new (
|
|
710
|
+
elements?: Iterable<string> | Iterable<RM>,
|
|
711
|
+
options?: TrieOptions<RM>
|
|
712
|
+
) => Trie<RM>;
|
|
713
|
+
return new Ctor(elements, options);
|
|
708
714
|
}
|
|
709
715
|
|
|
710
716
|
/**
|
|
@@ -2,4 +2,11 @@ import { LinearBaseOptions } from '../base';
|
|
|
2
2
|
|
|
3
3
|
export type DequeOptions<E, R> = {
|
|
4
4
|
bucketSize?: number;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* When the ratio of used buckets to total buckets falls below this threshold
|
|
8
|
+
* after a shift/pop, auto-compact is triggered. Set to 0 to disable.
|
|
9
|
+
* Default: 0.5 (compact when less than half the buckets are in use).
|
|
10
|
+
*/
|
|
11
|
+
autoCompactRatio?: number;
|
|
5
12
|
} & LinearBaseOptions<E, R>;
|
package/src/utils/utils.ts
CHANGED
|
@@ -77,8 +77,10 @@ export const getMSB = (value: number): number => {
|
|
|
77
77
|
* error message to be thrown if the index is out of bounds. By default, if no message is provided when
|
|
78
78
|
* calling the `rangeCheck` function, the message "Index out of bounds." will be used.
|
|
79
79
|
*/
|
|
80
|
-
export const rangeCheck = (index: number, min: number, max: number, message
|
|
81
|
-
if (index < min || index > max)
|
|
80
|
+
export const rangeCheck = (index: number, min: number, max: number, message?: string): void => {
|
|
81
|
+
if (index < min || index > max) {
|
|
82
|
+
throw new RangeError(message ?? `Index ${index} is out of range [${min}, ${max}].`);
|
|
83
|
+
}
|
|
82
84
|
};
|
|
83
85
|
|
|
84
86
|
/**
|