stack-typed 1.48.1 → 1.48.3

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 (76) 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/avl-tree.d.ts +16 -16
  6. package/dist/data-structures/binary-tree/avl-tree.js +7 -7
  7. package/dist/data-structures/binary-tree/binary-tree.d.ts +121 -152
  8. package/dist/data-structures/binary-tree/binary-tree.js +140 -182
  9. package/dist/data-structures/binary-tree/bst.d.ts +28 -47
  10. package/dist/data-structures/binary-tree/bst.js +54 -57
  11. package/dist/data-structures/binary-tree/rb-tree.d.ts +15 -15
  12. package/dist/data-structures/binary-tree/rb-tree.js +7 -7
  13. package/dist/data-structures/binary-tree/tree-multimap.d.ts +22 -22
  14. package/dist/data-structures/binary-tree/tree-multimap.js +11 -11
  15. package/dist/data-structures/graph/abstract-graph.d.ts +44 -6
  16. package/dist/data-structures/graph/abstract-graph.js +50 -27
  17. package/dist/data-structures/hash/hash-map.d.ts +59 -100
  18. package/dist/data-structures/hash/hash-map.js +69 -173
  19. package/dist/data-structures/heap/heap.d.ts +50 -7
  20. package/dist/data-structures/heap/heap.js +60 -30
  21. package/dist/data-structures/index.d.ts +1 -0
  22. package/dist/data-structures/index.js +1 -0
  23. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +38 -51
  24. package/dist/data-structures/linked-list/doubly-linked-list.js +46 -73
  25. package/dist/data-structures/linked-list/singly-linked-list.d.ts +32 -51
  26. package/dist/data-structures/linked-list/singly-linked-list.js +40 -73
  27. package/dist/data-structures/queue/deque.d.ts +29 -51
  28. package/dist/data-structures/queue/deque.js +36 -71
  29. package/dist/data-structures/queue/queue.d.ts +49 -48
  30. package/dist/data-structures/queue/queue.js +69 -82
  31. package/dist/data-structures/stack/stack.d.ts +43 -10
  32. package/dist/data-structures/stack/stack.js +50 -31
  33. package/dist/data-structures/trie/trie.d.ts +41 -6
  34. package/dist/data-structures/trie/trie.js +53 -32
  35. package/dist/interfaces/binary-tree.d.ts +6 -6
  36. package/dist/types/common.d.ts +11 -8
  37. package/dist/types/common.js +6 -1
  38. package/dist/types/data-structures/base/base.d.ts +5 -0
  39. package/dist/types/data-structures/base/base.js +2 -0
  40. package/dist/types/data-structures/base/index.d.ts +1 -0
  41. package/dist/types/data-structures/base/index.js +17 -0
  42. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -3
  43. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +4 -4
  44. package/dist/types/data-structures/binary-tree/bst.d.ts +6 -6
  45. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -3
  46. package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +3 -3
  47. package/dist/types/data-structures/index.d.ts +1 -0
  48. package/dist/types/data-structures/index.js +1 -0
  49. package/package.json +2 -2
  50. package/src/data-structures/base/index.ts +1 -0
  51. package/src/data-structures/base/iterable-base.ts +329 -0
  52. package/src/data-structures/binary-tree/avl-tree.ts +20 -21
  53. package/src/data-structures/binary-tree/binary-tree.ts +222 -267
  54. package/src/data-structures/binary-tree/bst.ts +86 -82
  55. package/src/data-structures/binary-tree/rb-tree.ts +25 -26
  56. package/src/data-structures/binary-tree/tree-multimap.ts +30 -35
  57. package/src/data-structures/graph/abstract-graph.ts +55 -28
  58. package/src/data-structures/hash/hash-map.ts +76 -185
  59. package/src/data-structures/heap/heap.ts +63 -36
  60. package/src/data-structures/index.ts +1 -0
  61. package/src/data-structures/linked-list/doubly-linked-list.ts +50 -79
  62. package/src/data-structures/linked-list/singly-linked-list.ts +45 -80
  63. package/src/data-structures/queue/deque.ts +40 -82
  64. package/src/data-structures/queue/queue.ts +72 -87
  65. package/src/data-structures/stack/stack.ts +53 -34
  66. package/src/data-structures/trie/trie.ts +58 -35
  67. package/src/interfaces/binary-tree.ts +5 -6
  68. package/src/types/common.ts +11 -8
  69. package/src/types/data-structures/base/base.ts +6 -0
  70. package/src/types/data-structures/base/index.ts +1 -0
  71. package/src/types/data-structures/binary-tree/avl-tree.ts +3 -3
  72. package/src/types/data-structures/binary-tree/binary-tree.ts +6 -5
  73. package/src/types/data-structures/binary-tree/bst.ts +6 -6
  74. package/src/types/data-structures/binary-tree/rb-tree.ts +3 -3
  75. package/src/types/data-structures/binary-tree/tree-multimap.ts +3 -3
  76. package/src/types/data-structures/index.ts +1 -0
@@ -5,26 +5,21 @@
5
5
  * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
- import type {
9
- BSTNodeKeyOrNode,
10
- BTNKey,
11
- BTNodeExemplar,
12
- TreeMultimapNodeNested,
13
- TreeMultimapOptions
14
- } from '../../types';
8
+ import type { BSTNodeKeyOrNode, BTNodeExemplar, TreeMultimapNodeNested, TreeMultimapOptions } from '../../types';
15
9
  import { BiTreeDeleteResult, BTNCallback, FamilyPosition, IterationType, TreeMultimapNested } from '../../types';
16
10
  import { IBinaryTree } from '../../interfaces';
17
11
  import { AVLTree, AVLTreeNode } from './avl-tree';
18
12
 
19
13
  export class TreeMultimapNode<
14
+ K = any,
20
15
  V = any,
21
- N extends TreeMultimapNode<V, N> = TreeMultimapNodeNested<V>
22
- > extends AVLTreeNode<V, N> {
16
+ N extends TreeMultimapNode<K, V, N> = TreeMultimapNodeNested<K, V>
17
+ > extends AVLTreeNode<K, V, N> {
23
18
  count: number;
24
19
 
25
20
  /**
26
21
  * The constructor function initializes a BinaryTreeNode object with a key, value, and count.
27
- * @param {BTNKey} key - The `key` parameter is of type `BTNKey` and represents the unique identifier
22
+ * @param {K} key - The `key` parameter is of type `K` and represents the unique identifier
28
23
  * of the binary tree node.
29
24
  * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the value of the binary
30
25
  * tree node. If no value is provided, it will be `undefined`.
@@ -32,7 +27,7 @@ export class TreeMultimapNode<
32
27
  * occurs in a binary tree node. It has a default value of 1, which means that if no value is provided for the `count`
33
28
  * parameter when creating a new instance of the `BinaryTreeNode` class.
34
29
  */
35
- constructor(key: BTNKey, value?: V, count = 1) {
30
+ constructor(key: K, value?: V, count = 1) {
36
31
  super(key, value);
37
32
  this.count = count;
38
33
  }
@@ -41,12 +36,12 @@ export class TreeMultimapNode<
41
36
  /**
42
37
  * The only distinction between a TreeMultimap and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.
43
38
  */
44
- export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultimapNode<V, TreeMultimapNodeNested<V>>,
45
- TREE extends TreeMultimap<V, N, TREE> = TreeMultimap<V, N, TreeMultimapNested<V, N>>>
46
- extends AVLTree<V, N, TREE>
47
- implements IBinaryTree<V, N, TREE> {
39
+ export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N> = TreeMultimapNode<K, V, TreeMultimapNodeNested<K, V>>,
40
+ TREE extends TreeMultimap<K, V, N, TREE> = TreeMultimap<K, V, N, TreeMultimapNested<K, V, N>>>
41
+ extends AVLTree<K, V, N, TREE>
42
+ implements IBinaryTree<K, V, N, TREE> {
48
43
 
49
- constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<TreeMultimapOptions>) {
44
+ constructor(elements?: Iterable<BTNodeExemplar<K, V, N>>, options?: Partial<TreeMultimapOptions<K>>) {
50
45
  super([], options);
51
46
  if (elements) this.addMany(elements);
52
47
  }
@@ -62,43 +57,43 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
62
57
 
63
58
  /**
64
59
  * The function creates a new BSTNode with the given key, value, and count.
65
- * @param {BTNKey} key - The key parameter is the unique identifier for the binary tree node. It is used to
60
+ * @param {K} key - The key parameter is the unique identifier for the binary tree node. It is used to
66
61
  * distinguish one node from another in the tree.
67
62
  * @param {N} value - The `value` parameter represents the value that will be stored in the binary search tree node.
68
63
  * @param {number} [count] - The "count" parameter is an optional parameter of type number. It represents the number of
69
64
  * occurrences of the value in the binary search tree node. If not provided, the count will default to 1.
70
65
  * @returns A new instance of the BSTNode class with the specified key, value, and count (if provided).
71
66
  */
72
- override createNode(key: BTNKey, value?: V, count?: number): N {
67
+ override createNode(key: K, value?: V, count?: number): N {
73
68
  return new TreeMultimapNode(key, value, count) as N;
74
69
  }
75
70
 
76
- override createTree(options?: TreeMultimapOptions): TREE {
77
- return new TreeMultimap<V, N, TREE>([], {
71
+ override createTree(options?: TreeMultimapOptions<K>): TREE {
72
+ return new TreeMultimap<K, V, N, TREE>([], {
78
73
  iterationType: this.iterationType,
79
- comparator: this.comparator, ...options
74
+ variant: this.variant, ...options
80
75
  }) as TREE;
81
76
  }
82
77
 
83
78
  /**
84
79
  * The function checks if an exemplar is an instance of the TreeMultimapNode class.
85
- * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N>`.
80
+ * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`.
86
81
  * @returns a boolean value indicating whether the exemplar is an instance of the TreeMultimapNode
87
82
  * class.
88
83
  */
89
- override isNode(exemplar: BTNodeExemplar<V, N>): exemplar is N {
84
+ override isNode(exemplar: BTNodeExemplar<K, V, N>): exemplar is N {
90
85
  return exemplar instanceof TreeMultimapNode;
91
86
  }
92
87
 
93
88
  /**
94
89
  * The function `exemplarToNode` converts an exemplar object into a node object.
95
- * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N>`, where `V` represents
90
+ * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`, where `V` represents
96
91
  * the value type and `N` represents the node type.
97
92
  * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of
98
93
  * times the node should be created. If not provided, it defaults to 1.
99
94
  * @returns a value of type `N` (the generic type parameter) or `undefined`.
100
95
  */
101
- override exemplarToNode(exemplar: BTNodeExemplar<V, N>, count = 1): N | undefined {
96
+ override exemplarToNode(exemplar: BTNodeExemplar<K, V, N>, count = 1): N | undefined {
102
97
  let node: N | undefined;
103
98
  if (exemplar === undefined || exemplar === null) {
104
99
  return;
@@ -111,7 +106,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
111
106
  } else {
112
107
  node = this.createNode(key, value, count);
113
108
  }
114
- } else if (this.isNodeKey(exemplar)) {
109
+ } else if (this.isNotNodeInstance(exemplar)) {
115
110
  node = this.createNode(exemplar, undefined, count);
116
111
  } else {
117
112
  return;
@@ -136,7 +131,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
136
131
  * is 1.
137
132
  * @returns either a node (`N`) or `undefined`.
138
133
  */
139
- override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>, count = 1): N | undefined {
134
+ override add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>, count = 1): N | undefined {
140
135
  const newNode = this.exemplarToNode(keyOrNodeOrEntry, count);
141
136
  if (newNode === undefined) return;
142
137
 
@@ -163,7 +158,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
163
158
  * either keys, nodes, or entries.
164
159
  * @returns The method is returning an array of type `N | undefined`.
165
160
  */
166
- override addMany(keysOrNodesOrEntries: Iterable<BTNodeExemplar<V, N>>): (N | undefined)[] {
161
+ override addMany(keysOrNodesOrEntries: Iterable<BTNodeExemplar<K, V, N>>): (N | undefined)[] {
167
162
  return super.addMany(keysOrNodesOrEntries);
168
163
  }
169
164
 
@@ -345,13 +340,13 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
345
340
  * @param {N | undefined} newNode - The `newNode` parameter represents the node that needs to be
346
341
  * added to the binary tree. It can be of type `N` (which represents a node in the binary tree) or
347
342
  * `undefined` if there is no node to add.
348
- * @param {BTNKey | N | undefined} parent - The `parent` parameter represents the parent node to
343
+ * @param {K | N | undefined} parent - The `parent` parameter represents the parent node to
349
344
  * which the new node will be added as a child. It can be either a node object (`N`) or a key value
350
- * (`BTNKey`).
345
+ * (`K`).
351
346
  * @returns The method `_addTo` returns either the `parent.left` or `parent.right` node that was
352
347
  * added, or `undefined` if no node was added.
353
348
  */
354
- protected override _addTo(newNode: N | undefined, parent: BSTNodeKeyOrNode<N>): N | undefined {
349
+ protected override _addTo(newNode: N | undefined, parent: BSTNodeKeyOrNode<K, N>): N | undefined {
355
350
  parent = this.ensureNode(parent);
356
351
  if (parent) {
357
352
  if (parent.left === undefined) {
@@ -379,14 +374,14 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
379
374
 
380
375
  /**
381
376
  * The `_swapProperties` function swaps the key, value, count, and height properties between two nodes.
382
- * @param {BTNKey | N | undefined} srcNode - The `srcNode` parameter represents the source node from
383
- * which the values will be swapped. It can be of type `BTNKey`, `N`, or `undefined`.
384
- * @param {BTNKey | N | undefined} destNode - The `destNode` parameter represents the destination
377
+ * @param {K | N | undefined} srcNode - The `srcNode` parameter represents the source node from
378
+ * which the values will be swapped. It can be of type `K`, `N`, or `undefined`.
379
+ * @param {K | N | undefined} destNode - The `destNode` parameter represents the destination
385
380
  * node where the values from the source node will be swapped to.
386
381
  * @returns either the `destNode` object if both `srcNode` and `destNode` are defined, or `undefined`
387
382
  * if either `srcNode` or `destNode` is undefined.
388
383
  */
389
- protected override _swapProperties(srcNode: BSTNodeKeyOrNode<N>, destNode: BSTNodeKeyOrNode<N>): N | undefined {
384
+ protected override _swapProperties(srcNode: BSTNodeKeyOrNode<K, N>, destNode: BSTNodeKeyOrNode<K, N>): N | undefined {
390
385
  srcNode = this.ensureNode(srcNode);
391
386
  destNode = this.ensureNode(destNode);
392
387
  if (srcNode && destNode) {
@@ -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)