min-heap-typed 1.48.1 → 1.48.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/data-structures/base/index.d.ts +1 -0
  2. package/dist/data-structures/base/index.js +17 -0
  3. package/dist/data-structures/base/iterable-base.d.ts +232 -0
  4. package/dist/data-structures/base/iterable-base.js +312 -0
  5. package/dist/data-structures/binary-tree/binary-tree.d.ts +36 -69
  6. package/dist/data-structures/binary-tree/binary-tree.js +78 -129
  7. package/dist/data-structures/graph/abstract-graph.d.ts +44 -6
  8. package/dist/data-structures/graph/abstract-graph.js +50 -27
  9. package/dist/data-structures/hash/hash-map.d.ts +59 -100
  10. package/dist/data-structures/hash/hash-map.js +69 -173
  11. package/dist/data-structures/heap/heap.d.ts +50 -7
  12. package/dist/data-structures/heap/heap.js +60 -30
  13. package/dist/data-structures/index.d.ts +1 -0
  14. package/dist/data-structures/index.js +1 -0
  15. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +38 -51
  16. package/dist/data-structures/linked-list/doubly-linked-list.js +46 -73
  17. package/dist/data-structures/linked-list/singly-linked-list.d.ts +32 -51
  18. package/dist/data-structures/linked-list/singly-linked-list.js +40 -73
  19. package/dist/data-structures/queue/deque.d.ts +29 -51
  20. package/dist/data-structures/queue/deque.js +36 -71
  21. package/dist/data-structures/queue/queue.d.ts +49 -48
  22. package/dist/data-structures/queue/queue.js +69 -82
  23. package/dist/data-structures/stack/stack.d.ts +43 -10
  24. package/dist/data-structures/stack/stack.js +50 -31
  25. package/dist/data-structures/trie/trie.d.ts +41 -6
  26. package/dist/data-structures/trie/trie.js +53 -32
  27. package/dist/types/data-structures/base/base.d.ts +5 -0
  28. package/dist/types/data-structures/base/base.js +2 -0
  29. package/dist/types/data-structures/base/index.d.ts +1 -0
  30. package/dist/types/data-structures/base/index.js +17 -0
  31. package/dist/types/data-structures/index.d.ts +1 -0
  32. package/dist/types/data-structures/index.js +1 -0
  33. package/package.json +2 -2
  34. package/src/data-structures/base/index.ts +1 -0
  35. package/src/data-structures/base/iterable-base.ts +329 -0
  36. package/src/data-structures/binary-tree/binary-tree.ts +82 -138
  37. package/src/data-structures/graph/abstract-graph.ts +55 -28
  38. package/src/data-structures/hash/hash-map.ts +76 -185
  39. package/src/data-structures/heap/heap.ts +63 -36
  40. package/src/data-structures/index.ts +1 -0
  41. package/src/data-structures/linked-list/doubly-linked-list.ts +50 -79
  42. package/src/data-structures/linked-list/singly-linked-list.ts +45 -80
  43. package/src/data-structures/queue/deque.ts +40 -82
  44. package/src/data-structures/queue/queue.ts +72 -87
  45. package/src/data-structures/stack/stack.ts +53 -34
  46. package/src/data-structures/trie/trie.ts +58 -35
  47. package/src/types/data-structures/base/base.ts +6 -0
  48. package/src/types/data-structures/base/index.ts +1 -0
  49. package/src/types/data-structures/index.ts +1 -0
@@ -8,8 +8,10 @@
8
8
  import { uuidV4 } from '../../utils';
9
9
  import { PriorityQueue } from '../priority-queue';
10
10
  import type { DijkstraResult, VertexKey } from '../../types';
11
+ import { PairCallback } from "../../types";
11
12
  import { IGraph } from '../../interfaces';
12
13
  import { Queue } from '../queue';
14
+ import { IterablePairBase } from "../base";
13
15
 
14
16
  export abstract class AbstractVertex<V = any> {
15
17
  key: VertexKey;
@@ -64,7 +66,11 @@ export abstract class AbstractGraph<
64
66
  E = any,
65
67
  VO extends AbstractVertex<V> = AbstractVertex<V>,
66
68
  EO extends AbstractEdge<E> = AbstractEdge<E>
67
- > implements IGraph<V, E, VO, EO> {
69
+ > extends IterablePairBase<VertexKey, V | undefined> implements IGraph<V, E, VO, EO> {
70
+ constructor() {
71
+ super();
72
+ }
73
+
68
74
  protected _vertices: Map<VertexKey, VO> = new Map<VertexKey, VO>();
69
75
 
70
76
  get vertices(): Map<VertexKey, VO> {
@@ -1159,50 +1165,71 @@ export abstract class AbstractGraph<
1159
1165
  return this.tarjan(false, true, false, false).bridges;
1160
1166
  }
1161
1167
 
1162
- * [Symbol.iterator](): Iterator<[VertexKey, V | undefined]> {
1163
- for (const vertex of this._vertices.values()) {
1164
- yield [vertex.key, vertex.value];
1165
- }
1166
- }
1167
-
1168
- forEach(callback: (entry: [VertexKey, V | undefined], index: number, map: Map<VertexKey, VO>) => void): void {
1169
- let index = 0;
1170
- for (const vertex of this) {
1171
- callback(vertex, index, this._vertices);
1172
- index++;
1173
- }
1174
- }
1168
+ /**
1169
+ * Time Complexity: O(n)
1170
+ * Space Complexity: O(n)
1171
+ */
1175
1172
 
1176
- filter(predicate: (entry: [VertexKey, V | undefined], index: number, map: Map<VertexKey, VO>) => boolean): [VertexKey, V | undefined][] {
1173
+ /**
1174
+ * Time Complexity: O(n)
1175
+ * Space Complexity: O(n)
1176
+ *
1177
+ * The `filter` function iterates over key-value pairs in a data structure and returns an array of
1178
+ * pairs that satisfy a given predicate.
1179
+ * @param predicate - The `predicate` parameter is a callback function that takes four arguments:
1180
+ * `value`, `key`, `index`, and `this`. It is used to determine whether an element should be included
1181
+ * in the filtered array. The callback function should return `true` if the element should be
1182
+ * included, and `
1183
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
1184
+ * specify the value of `this` within the `predicate` function. It is used when you want to bind a
1185
+ * specific object as the context for the `predicate` function. If `thisArg` is provided, it will be
1186
+ * @returns The `filter` method returns an array of key-value pairs `[VertexKey, V | undefined][]`
1187
+ * that satisfy the given predicate function.
1188
+ */
1189
+ filter(predicate: PairCallback<VertexKey, V | undefined, boolean>, thisArg?: any): [VertexKey, V | undefined][] {
1177
1190
  const filtered: [VertexKey, V | undefined][] = [];
1178
1191
  let index = 0;
1179
- for (const entry of this) {
1180
- if (predicate(entry, index, this._vertices)) {
1181
- filtered.push(entry);
1192
+ for (const [key, value] of this) {
1193
+ if (predicate.call(thisArg, value, key, index, this)) {
1194
+ filtered.push([key, value]);
1182
1195
  }
1183
1196
  index++;
1184
1197
  }
1185
1198
  return filtered;
1186
1199
  }
1187
1200
 
1188
- map<T>(callback: (entry: [VertexKey, V | undefined], index: number, map: Map<VertexKey, VO>) => T): T[] {
1201
+ /**
1202
+ * Time Complexity: O(n)
1203
+ * Space Complexity: O(n)
1204
+ */
1205
+
1206
+ /**
1207
+ * Time Complexity: O(n)
1208
+ * Space Complexity: O(n)
1209
+ *
1210
+ * The `map` function iterates over the elements of a collection and applies a callback function to
1211
+ * each element, returning an array of the results.
1212
+ * @param callback - The callback parameter is a function that will be called for each element in the
1213
+ * map. It takes four arguments:
1214
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
1215
+ * specify the value of `this` within the callback function. If `thisArg` is provided, it will be
1216
+ * used as the `this` value when calling the callback function. If `thisArg` is not provided, `
1217
+ * @returns The `map` function is returning an array of type `T[]`.
1218
+ */
1219
+ map<T>(callback: PairCallback<VertexKey, V | undefined, T>, thisArg?: any): T[] {
1189
1220
  const mapped: T[] = [];
1190
1221
  let index = 0;
1191
- for (const entry of this) {
1192
- mapped.push(callback(entry, index, this._vertices));
1222
+ for (const [key, value] of this) {
1223
+ mapped.push(callback.call(thisArg, value, key, index, this));
1193
1224
  index++;
1194
1225
  }
1195
1226
  return mapped;
1196
1227
  }
1197
1228
 
1198
- reduce<T>(callback: (accumulator: T, entry: [VertexKey, V | undefined], index: number, map: Map<VertexKey, VO>) => T, initialValue: T): T {
1199
- let accumulator: T = initialValue;
1200
- let index = 0;
1201
- for (const entry of this) {
1202
- accumulator = callback(accumulator, entry, index, this._vertices);
1203
- index++;
1229
+ protected* _getIterator(): IterableIterator<[VertexKey, V | undefined]> {
1230
+ for (const vertex of this._vertices.values()) {
1231
+ yield [vertex.key, vertex.value];
1204
1232
  }
1205
- return accumulator;
1206
1233
  }
1207
1234
 
1208
1235
  protected abstract _addEdgeOnly(edge: EO): boolean;
@@ -7,9 +7,10 @@
7
7
  */
8
8
 
9
9
  import { isWeakKey, rangeCheck } from '../../utils';
10
- import { HashMapLinkedNode, HashMapOptions, HashMapStoreItem } from '../../types';
10
+ import { HashMapLinkedNode, HashMapOptions, HashMapStoreItem, PairCallback } from '../../types';
11
+ import { IterablePairBase } from "../base";
11
12
 
12
- export class HashMap<K = any, V = any> {
13
+ export class HashMap<K = any, V = any> extends IterablePairBase<K, V> {
13
14
  protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};
14
15
  protected _objMap: Map<object, V> = new Map();
15
16
 
@@ -24,6 +25,7 @@ export class HashMap<K = any, V = any> {
24
25
  constructor(elements: Iterable<[K, V]> = [], options?: {
25
26
  hashFn: (key: K) => string
26
27
  }) {
28
+ super();
27
29
  if (options) {
28
30
  const { hashFn } = options;
29
31
  if (hashFn) {
@@ -145,102 +147,14 @@ export class HashMap<K = any, V = any> {
145
147
  }
146
148
 
147
149
  /**
148
- * The function returns an iterator that yields key-value pairs from both an object store and an
149
- * object map.
150
- */
151
- * [Symbol.iterator](): IterableIterator<[K, V]> {
152
- for (const node of Object.values(this._store)) {
153
- yield [node.key, node.value] as [K, V];
154
- }
155
- for (const node of this._objMap) {
156
- yield node as [K, V];
157
- }
158
- }
159
-
160
- /**
161
- * The function returns an iterator that yields key-value pairs from the object.
162
- */
163
- * entries(): IterableIterator<[K, V]> {
164
- for (const item of this) {
165
- yield item;
166
- }
167
- }
168
-
169
- /**
170
- * The function `keys()` returns an iterator that yields all the keys of the object.
171
- */
172
- * keys(): IterableIterator<K> {
173
- for (const [key] of this) {
174
- yield key;
175
- }
176
- }
177
-
178
- * values(): IterableIterator<V> {
179
- for (const [, value] of this) {
180
- yield value;
181
- }
182
- }
183
-
184
- /**
185
- * The `every` function checks if every element in a HashMap satisfies a given predicate function.
186
- * @param predicate - The predicate parameter is a function that takes four arguments: value, key,
187
- * index, and map. It is used to test each element in the map against a condition. If the predicate
188
- * function returns false for any element, the every() method will return false. If the predicate
189
- * function returns true for all
190
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
191
- * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be
192
- * passed as the `this` value to the `predicate` function. If `thisArg` is
193
- * @returns The method is returning a boolean value. It returns true if the predicate function
194
- * returns true for every element in the map, and false otherwise.
150
+ * Time Complexity: O(n)
151
+ * Space Complexity: O(n)
195
152
  */
196
- every(predicate: (value: V, key: K, index: number, map: HashMap<K, V>) => boolean, thisArg?: any): boolean {
197
- let index = 0;
198
- for (const [key, value] of this) {
199
- if (!predicate.call(thisArg, value, key, index++, this)) {
200
- return false;
201
- }
202
- }
203
- return true;
204
- }
205
-
206
- /**
207
- * The "some" function checks if at least one element in a HashMap satisfies a given predicate.
208
- * @param predicate - The `predicate` parameter is a function that takes four arguments: `value`,
209
- * `key`, `index`, and `map`. It is used to determine whether a specific condition is met for a given
210
- * key-value pair in the `HashMap`.
211
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
212
- * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be
213
- * passed as the `this` value to the `predicate` function. If `thisArg` is
214
- * @returns a boolean value. It returns true if the predicate function returns true for any element
215
- * in the map, and false otherwise.
216
- */
217
- some(predicate: (value: V, key: K, index: number, map: HashMap<K, V>) => boolean, thisArg?: any): boolean {
218
- let index = 0;
219
- for (const [key, value] of this) {
220
- if (predicate.call(thisArg, value, key, index++, this)) {
221
- return true;
222
- }
223
- }
224
- return false;
225
- }
226
-
227
- /**
228
- * The `forEach` function iterates over the elements of a HashMap and applies a callback function to
229
- * each element.
230
- * @param callbackfn - A function that will be called for each key-value pair in the HashMap. It
231
- * takes four parameters:
232
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
233
- * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will
234
- * be passed as the `this` value inside the `callbackfn` function. If `thisArg
235
- */
236
- forEach(callbackfn: (value: V, key: K, index: number, map: HashMap<K, V>) => void, thisArg?: any): void {
237
- let index = 0;
238
- for (const [key, value] of this) {
239
- callbackfn.call(thisArg, value, key, index++, this);
240
- }
241
- }
242
153
 
243
154
  /**
155
+ * Time Complexity: O(n)
156
+ * Space Complexity: O(n)
157
+ *
244
158
  * The `map` function in TypeScript creates a new HashMap by applying a callback function to each
245
159
  * key-value pair in the original HashMap.
246
160
  * @param callbackfn - The callback function that will be called for each key-value pair in the
@@ -251,7 +165,7 @@ export class HashMap<K = any, V = any> {
251
165
  * @returns The `map` method is returning a new `HashMap` object with the transformed values based on
252
166
  * the provided callback function.
253
167
  */
254
- map<U>(callbackfn: (value: V, key: K, index: number, map: HashMap<K, V>) => U, thisArg?: any): HashMap<K, U> {
168
+ map<U>(callbackfn: PairCallback<K, V, U>, thisArg?: any): HashMap<K, U> {
255
169
  const resultMap = new HashMap<K, U>();
256
170
  let index = 0;
257
171
  for (const [key, value] of this) {
@@ -261,6 +175,14 @@ export class HashMap<K = any, V = any> {
261
175
  }
262
176
 
263
177
  /**
178
+ * Time Complexity: O(n)
179
+ * Space Complexity: O(n)
180
+ */
181
+
182
+ /**
183
+ * Time Complexity: O(n)
184
+ * Space Complexity: O(n)
185
+ *
264
186
  * The `filter` function creates a new HashMap containing key-value pairs from the original HashMap
265
187
  * that satisfy a given predicate function.
266
188
  * @param predicate - The predicate parameter is a function that takes four arguments: value, key,
@@ -273,7 +195,7 @@ export class HashMap<K = any, V = any> {
273
195
  * @returns The `filter` method is returning a new `HashMap` object that contains the key-value pairs
274
196
  * from the original `HashMap` that pass the provided `predicate` function.
275
197
  */
276
- filter(predicate: (value: V, key: K, index: number, map: HashMap<K, V>) => boolean, thisArg?: any): HashMap<K, V> {
198
+ filter(predicate: PairCallback<K, V, boolean>, thisArg?: any): HashMap<K, V> {
277
199
  const filteredMap = new HashMap<K, V>();
278
200
  let index = 0;
279
201
  for (const [key, value] of this) {
@@ -284,28 +206,21 @@ export class HashMap<K = any, V = any> {
284
206
  return filteredMap;
285
207
  }
286
208
 
209
+ print(): void {
210
+ console.log([...this.entries()]);
211
+ }
212
+
287
213
  /**
288
- * The `reduce` function iterates over the elements of a HashMap and applies a callback function to
289
- * each element, accumulating a single value.
290
- * @param callbackfn - The callback function that will be called for each element in the HashMap. It
291
- * takes five parameters:
292
- * @param {U} initialValue - The initialValue parameter is the initial value of the accumulator. It
293
- * is the value that will be used as the first argument of the callback function when reducing the
294
- * elements of the map.
295
- * @returns The `reduce` method is returning the final value of the accumulator after iterating over
296
- * all the elements in the `HashMap`.
214
+ * The function returns an iterator that yields key-value pairs from both an object store and an
215
+ * object map.
297
216
  */
298
- reduce<U>(callbackfn: (accumulator: U, currentValue: V, currentKey: K, index: number, map: HashMap<K, V>) => U, initialValue: U): U {
299
- let accumulator = initialValue;
300
- let index = 0;
301
- for (const [key, value] of this) {
302
- accumulator = callbackfn(accumulator, value, key, index++, this);
217
+ protected* _getIterator(): IterableIterator<[K, V]> {
218
+ for (const node of Object.values(this._store)) {
219
+ yield [node.key, node.value] as [K, V];
220
+ }
221
+ for (const node of this._objMap) {
222
+ yield node as [K, V];
303
223
  }
304
- return accumulator;
305
- }
306
-
307
- print(): void{
308
- console.log([...this.entries()]);
309
224
  }
310
225
 
311
226
  protected _hashFn: (key: K) => string = (key: K) => String(key);
@@ -333,7 +248,7 @@ export class HashMap<K = any, V = any> {
333
248
  }
334
249
  }
335
250
 
336
- export class LinkedHashMap<K = any, V = any> {
251
+ export class LinkedHashMap<K = any, V = any> extends IterablePairBase<K, V> {
337
252
 
338
253
  protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};
339
254
  protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();
@@ -349,6 +264,7 @@ export class LinkedHashMap<K = any, V = any> {
349
264
  hashFn: (key: K) => String(key),
350
265
  objHashFn: (key: K) => (<object>key)
351
266
  }) {
267
+ super();
352
268
  this._sentinel = <HashMapLinkedNode<K, V>>{};
353
269
  this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;
354
270
 
@@ -492,18 +408,6 @@ export class LinkedHashMap<K = any, V = any> {
492
408
  }
493
409
  }
494
410
 
495
- keys(): K[] {
496
- const keys: K[] = [];
497
- for (const [key] of this) keys.push(key);
498
- return keys;
499
- }
500
-
501
- values(): V[] {
502
- const values: V[] = [];
503
- for (const [, value] of this) values.push(value);
504
- return values;
505
- }
506
-
507
411
  /**
508
412
  * Time Complexity: O(1)
509
413
  * Space Complexity: O(1)
@@ -644,36 +548,30 @@ export class LinkedHashMap<K = any, V = any> {
644
548
  }
645
549
 
646
550
  /**
647
- * Time Complexity: O(n), where n is the number of elements in the LinkedHashMap.
648
- * Space Complexity: O(1)
649
- *
650
- * The `forEach` function iterates over each element in a LinkedHashMap and executes a callback function on
651
- * each element.
652
- * @param callback - The callback parameter is a function that will be called for each element in the
653
- * LinkedHashMap. It takes three arguments:
551
+ * Time Complexity: O(n)
552
+ * Space Complexity: O(n)
654
553
  */
655
- forEach(callback: (element: [K, V], index: number, hashMap: LinkedHashMap<K, V>) => void) {
656
- let index = 0;
657
- let node = this._head;
658
- while (node !== this._sentinel) {
659
- callback(<[K, V]>[node.key, node.value], index++, this);
660
- node = node.next;
661
- }
662
- }
663
554
 
664
555
  /**
665
- * The `filter` function takes a predicate function and returns a new LinkedHashMap containing only the
666
- * key-value pairs that satisfy the predicate.
667
- * @param predicate - The `predicate` parameter is a function that takes two arguments: `element` and
668
- * `map`.
669
- * @returns a new LinkedHashMap object that contains the key-value pairs from the original LinkedHashMap that
670
- * satisfy the given predicate function.
671
- */
672
- filter(predicate: (element: [K, V], index: number, map: LinkedHashMap<K, V>) => boolean): LinkedHashMap<K, V> {
556
+ * Time Complexity: O(n)
557
+ * Space Complexity: O(n)
558
+ *
559
+ * The `filter` function creates a new `LinkedHashMap` containing key-value pairs from the original
560
+ * map that satisfy a given predicate function.
561
+ * @param predicate - The `predicate` parameter is a callback function that takes four arguments:
562
+ * `value`, `key`, `index`, and `this`. It should return a boolean value indicating whether the
563
+ * current element should be included in the filtered map or not.
564
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
565
+ * specify the value of `this` within the `predicate` function. It is used when you want to bind a
566
+ * specific object as the context for the `predicate` function. If `thisArg` is not provided, `this
567
+ * @returns a new `LinkedHashMap` object that contains the key-value pairs from the original
568
+ * `LinkedHashMap` object that satisfy the given predicate function.
569
+ */
570
+ filter(predicate: PairCallback<K, V, boolean>, thisArg?: any): LinkedHashMap<K, V> {
673
571
  const filteredMap = new LinkedHashMap<K, V>();
674
572
  let index = 0;
675
573
  for (const [key, value] of this) {
676
- if (predicate([key, value], index, this)) {
574
+ if (predicate.call(thisArg, value, key, index, this)) {
677
575
  filteredMap.set(key, value);
678
576
  }
679
577
  index++;
@@ -682,43 +580,40 @@ export class LinkedHashMap<K = any, V = any> {
682
580
  }
683
581
 
684
582
  /**
685
- * The `map` function takes a callback function and returns a new LinkedHashMap with the values transformed
686
- * by the callback.
687
- * @param callback - The `callback` parameter is a function that takes two arguments: `element` and
688
- * `map`.
689
- * @returns a new LinkedHashMap object with the values mapped according to the provided callback function.
583
+ * Time Complexity: O(n)
584
+ * Space Complexity: O(n)
690
585
  */
691
- map<NV>(callback: (element: [K, V], index: number, map: LinkedHashMap<K, V>) => NV): LinkedHashMap<K, NV> {
586
+
587
+ /**
588
+ * Time Complexity: O(n)
589
+ * Space Complexity: O(n)
590
+ *
591
+ * The `map` function in TypeScript creates a new `LinkedHashMap` by applying a callback function to
592
+ * each key-value pair in the original map.
593
+ * @param callback - The callback parameter is a function that will be called for each key-value pair
594
+ * in the map. It takes four arguments: the value of the current key-value pair, the key of the
595
+ * current key-value pair, the index of the current key-value pair, and the map itself. The callback
596
+ * function should
597
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
598
+ * specify the value of `this` within the callback function. If provided, the callback function will
599
+ * be called with `thisArg` as its `this` value. If not provided, `this` will refer to the current
600
+ * map
601
+ * @returns a new `LinkedHashMap` object with the values mapped according to the provided callback
602
+ * function.
603
+ */
604
+ map<NV>(callback: PairCallback<K, V, NV>, thisArg?: any): LinkedHashMap<K, NV> {
692
605
  const mappedMap = new LinkedHashMap<K, NV>();
693
606
  let index = 0;
694
607
  for (const [key, value] of this) {
695
- const newValue = callback([key, value], index, this);
608
+ const newValue = callback.call(thisArg, value, key, index, this);
696
609
  mappedMap.set(key, newValue);
697
610
  index++;
698
611
  }
699
612
  return mappedMap;
700
613
  }
701
614
 
702
- /**
703
- * The `reduce` function iterates over the elements of a LinkedHashMap and applies a callback function to
704
- * each element, accumulating a single value.
705
- * @param callback - The callback parameter is a function that takes three arguments: accumulator,
706
- * element, and map. It is called for each element in the LinkedHashMap and is used to accumulate a single
707
- * result.
708
- * @param {A} initialValue - The `initialValue` parameter is the initial value of the accumulator. It
709
- * is the value that will be passed as the first argument to the `callback` function when reducing
710
- * the elements of the map.
711
- * @returns The `reduce` function is returning the final value of the accumulator after iterating
712
- * over all the elements in the LinkedHashMap and applying the callback function to each element.
713
- */
714
- reduce<A>(callback: (accumulator: A, element: [K, V], index: number, map: LinkedHashMap<K, V>) => A, initialValue: A): A {
715
- let accumulator = initialValue;
716
- let index = 0;
717
- for (const entry of this) {
718
- accumulator = callback(accumulator, entry, index, this);
719
- index++;
720
- }
721
- return accumulator;
615
+ print() {
616
+ console.log([...this]);
722
617
  }
723
618
 
724
619
  /**
@@ -727,7 +622,7 @@ export class LinkedHashMap<K = any, V = any> {
727
622
  *
728
623
  * The above function is an iterator that yields key-value pairs from a linked list.
729
624
  */
730
- * [Symbol.iterator]() {
625
+ protected* _getIterator() {
731
626
  let node = this._head;
732
627
  while (node !== this._sentinel) {
733
628
  yield <[K, V]>[node.key, node.value];
@@ -735,10 +630,6 @@ export class LinkedHashMap<K = any, V = any> {
735
630
  }
736
631
  }
737
632
 
738
- print() {
739
- console.log([...this]);
740
- }
741
-
742
633
  /**
743
634
  * Time Complexity: O(1)
744
635
  * Space Complexity: O(1)
@@ -5,13 +5,15 @@
5
5
  * @license MIT License
6
6
  */
7
7
 
8
- import type { Comparator, DFSOrderPattern } from '../../types';
8
+ import type { Comparator, DFSOrderPattern, ElementCallback } from '../../types';
9
9
  import { HeapOptions } from "../../types";
10
+ import { IterableElementBase } from "../base";
10
11
 
11
- export class Heap<E = any> {
12
+ export class Heap<E = any> extends IterableElementBase<E> {
12
13
  options: HeapOptions<E>;
13
14
 
14
15
  constructor(elements?: Iterable<E>, options?: HeapOptions<E>) {
16
+ super();
15
17
  const defaultComparator = (a: E, b: E) => {
16
18
  if (!(typeof a === 'number' && typeof b === 'number')) {
17
19
  throw new Error('The a, b params of compare function must be number');
@@ -339,56 +341,75 @@ export class Heap<E = any> {
339
341
  for (let i = Math.floor(this.size / 2); i >= 0; i--) this._sinkDown(i, this.elements.length >> 1);
340
342
  }
341
343
 
342
- * [Symbol.iterator]() {
343
- for (const element of this.elements) {
344
- yield element;
345
- }
346
- }
347
-
348
- forEach(callback: (element: E, index: number, heap: this) => void): void {
349
- let index = 0;
350
- for (const el of this) {
351
- callback(el, index, this);
352
- index++;
353
- }
354
- }
344
+ /**
345
+ * Time Complexity: O(n)
346
+ * Space Complexity: O(n)
347
+ */
355
348
 
356
- filter(predicate: (element: E, index: number, heap: Heap<E>) => boolean): Heap<E> {
357
- const filteredHeap: Heap<E> = new Heap<E>([], this.options);
349
+ /**
350
+ * Time Complexity: O(n)
351
+ * Space Complexity: O(n)
352
+ *
353
+ * The `filter` function creates a new Heap object containing elements that pass a given callback
354
+ * function.
355
+ * @param callback - The `callback` parameter is a function that will be called for each element in
356
+ * the heap. It takes three arguments: the current element, the index of the current element, and the
357
+ * heap itself. The callback function should return a boolean value indicating whether the current
358
+ * element should be included in the filtered list
359
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
360
+ * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be
361
+ * passed as the `this` value to the `callback` function. If `thisArg` is
362
+ * @returns The `filter` method is returning a new `Heap` object that contains the elements that pass
363
+ * the filter condition specified by the `callback` function.
364
+ */
365
+ filter(callback: ElementCallback<E, boolean>, thisArg?: any): Heap<E> {
366
+ const filteredList = new Heap<E>();
358
367
  let index = 0;
359
- for (const el of this) {
360
- if (predicate(el, index, this)) {
361
- filteredHeap.push(el);
368
+ for (const current of this) {
369
+ if (callback.call(thisArg, current, index, this)) {
370
+ filteredList.push(current);
362
371
  }
363
372
  index++;
364
373
  }
365
- return filteredHeap;
374
+ return filteredList;
366
375
  }
367
376
 
368
- map<T>(callback: (element: E, index: number, heap: Heap<E>) => T, comparator: Comparator<T>): Heap<T> {
377
+ /**
378
+ * Time Complexity: O(n)
379
+ * Space Complexity: O(n)
380
+ */
381
+
382
+ /**
383
+ * Time Complexity: O(n)
384
+ * Space Complexity: O(n)
385
+ *
386
+ * The `map` function creates a new heap by applying a callback function to each element of the
387
+ * original heap.
388
+ * @param callback - The callback parameter is a function that will be called for each element in the
389
+ * original heap. It takes three arguments: the current element, the index of the current element,
390
+ * and the original heap itself. The callback function should return a value of type T, which will be
391
+ * added to the mapped heap.
392
+ * @param comparator - The `comparator` parameter is a function that is used to compare elements in
393
+ * the heap. It takes two arguments, `a` and `b`, and returns a negative number if `a` is less than
394
+ * `b`, a positive number if `a` is greater than `b`, or
395
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
396
+ * specify the value of `this` within the callback function. It is used when you want to bind a
397
+ * specific object as the context for the callback function. If `thisArg` is not provided,
398
+ * `undefined` is used as
399
+ * @returns a new instance of the Heap class, which is created using the mapped elements from the
400
+ * original Heap.
401
+ */
402
+ map<T>(callback: ElementCallback<E, T>, comparator: Comparator<T>, thisArg?: any): Heap<T> {
369
403
 
370
404
  const mappedHeap: Heap<T> = new Heap<T>([], { comparator: comparator });
371
405
  let index = 0;
372
406
  for (const el of this) {
373
- mappedHeap.add(callback(el, index, this));
407
+ mappedHeap.add(callback.call(thisArg, el, index, this));
374
408
  index++;
375
409
  }
376
410
  return mappedHeap;
377
411
  }
378
412
 
379
- reduce<T>(
380
- callback: (accumulator: T, currentValue: E, currentIndex: number, heap: Heap<E>) => T,
381
- initialValue: T
382
- ): T {
383
- let accumulator: T = initialValue;
384
- let index = 0;
385
- for (const el of this) {
386
- accumulator = callback(accumulator, el, index, this);
387
- index++;
388
- }
389
- return accumulator;
390
- }
391
-
392
413
  /**
393
414
  * Time Complexity: O(log n)
394
415
  * Space Complexity: O(1)
@@ -398,6 +419,12 @@ export class Heap<E = any> {
398
419
  console.log([...this]);
399
420
  }
400
421
 
422
+ protected* _getIterator() {
423
+ for (const element of this.elements) {
424
+ yield element;
425
+ }
426
+ }
427
+
401
428
  /**
402
429
  * Time Complexity: O(n)
403
430
  * Space Complexity: O(1)
@@ -9,3 +9,4 @@ export * from './heap';
9
9
  export * from './priority-queue';
10
10
  export * from './matrix';
11
11
  export * from './trie';
12
+ export * from './base';