data-structure-typed 1.48.0 → 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 (144) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +24 -18
  3. package/benchmark/report.html +16 -16
  4. package/benchmark/report.json +188 -308
  5. package/dist/cjs/data-structures/base/index.d.ts +1 -0
  6. package/dist/cjs/data-structures/base/index.js +18 -0
  7. package/dist/cjs/data-structures/base/index.js.map +1 -0
  8. package/dist/cjs/data-structures/base/iterable-base.d.ts +232 -0
  9. package/dist/cjs/data-structures/base/iterable-base.js +313 -0
  10. package/dist/cjs/data-structures/base/iterable-base.js.map +1 -0
  11. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  12. package/dist/cjs/data-structures/binary-tree/binary-indexed-tree.js.map +1 -1
  13. package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +45 -40
  14. package/dist/cjs/data-structures/binary-tree/binary-tree.js +91 -88
  15. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  16. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  17. package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
  18. package/dist/cjs/data-structures/binary-tree/segment-tree.js.map +1 -1
  19. package/dist/cjs/data-structures/binary-tree/tree-multimap.d.ts +12 -0
  20. package/dist/cjs/data-structures/binary-tree/tree-multimap.js +16 -0
  21. package/dist/cjs/data-structures/binary-tree/tree-multimap.js.map +1 -1
  22. package/dist/cjs/data-structures/graph/abstract-graph.d.ts +44 -6
  23. package/dist/cjs/data-structures/graph/abstract-graph.js +50 -27
  24. package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
  25. package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
  26. package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
  27. package/dist/cjs/data-structures/hash/hash-map.d.ts +160 -44
  28. package/dist/cjs/data-structures/hash/hash-map.js +314 -82
  29. package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
  30. package/dist/cjs/data-structures/hash/hash-table.js.map +1 -1
  31. package/dist/cjs/data-structures/heap/heap.d.ts +50 -7
  32. package/dist/cjs/data-structures/heap/heap.js +60 -30
  33. package/dist/cjs/data-structures/heap/heap.js.map +1 -1
  34. package/dist/cjs/data-structures/heap/max-heap.js.map +1 -1
  35. package/dist/cjs/data-structures/heap/min-heap.js.map +1 -1
  36. package/dist/cjs/data-structures/index.d.ts +1 -0
  37. package/dist/cjs/data-structures/index.js +1 -0
  38. package/dist/cjs/data-structures/index.js.map +1 -1
  39. package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +38 -51
  40. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +46 -73
  41. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  42. package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +32 -51
  43. package/dist/cjs/data-structures/linked-list/singly-linked-list.js +40 -73
  44. package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
  45. package/dist/cjs/data-structures/linked-list/skip-linked-list.js.map +1 -1
  46. package/dist/cjs/data-structures/matrix/matrix2d.js.map +1 -1
  47. package/dist/cjs/data-structures/matrix/navigator.js.map +1 -1
  48. package/dist/cjs/data-structures/matrix/vector2d.js.map +1 -1
  49. package/dist/cjs/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  50. package/dist/cjs/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  51. package/dist/cjs/data-structures/queue/deque.d.ts +29 -51
  52. package/dist/cjs/data-structures/queue/deque.js +36 -71
  53. package/dist/cjs/data-structures/queue/deque.js.map +1 -1
  54. package/dist/cjs/data-structures/queue/queue.d.ts +49 -48
  55. package/dist/cjs/data-structures/queue/queue.js +69 -82
  56. package/dist/cjs/data-structures/queue/queue.js.map +1 -1
  57. package/dist/cjs/data-structures/stack/stack.d.ts +43 -10
  58. package/dist/cjs/data-structures/stack/stack.js +50 -31
  59. package/dist/cjs/data-structures/stack/stack.js.map +1 -1
  60. package/dist/cjs/data-structures/tree/tree.js.map +1 -1
  61. package/dist/cjs/data-structures/trie/trie.d.ts +41 -6
  62. package/dist/cjs/data-structures/trie/trie.js +53 -32
  63. package/dist/cjs/data-structures/trie/trie.js.map +1 -1
  64. package/dist/cjs/types/data-structures/base/base.d.ts +5 -0
  65. package/dist/cjs/types/data-structures/base/base.js +3 -0
  66. package/dist/cjs/types/data-structures/base/base.js.map +1 -0
  67. package/dist/cjs/types/data-structures/base/index.d.ts +1 -0
  68. package/dist/cjs/types/data-structures/base/index.js +18 -0
  69. package/dist/cjs/types/data-structures/base/index.js.map +1 -0
  70. package/dist/cjs/types/data-structures/hash/hash-map.d.ts +4 -0
  71. package/dist/cjs/types/data-structures/index.d.ts +1 -0
  72. package/dist/cjs/types/data-structures/index.js +1 -0
  73. package/dist/cjs/types/data-structures/index.js.map +1 -1
  74. package/dist/cjs/utils/utils.js.map +1 -1
  75. package/dist/mjs/data-structures/base/index.d.ts +1 -0
  76. package/dist/mjs/data-structures/base/index.js +1 -0
  77. package/dist/mjs/data-structures/base/iterable-base.d.ts +232 -0
  78. package/dist/mjs/data-structures/base/iterable-base.js +307 -0
  79. package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +45 -40
  80. package/dist/mjs/data-structures/binary-tree/binary-tree.js +91 -88
  81. package/dist/mjs/data-structures/binary-tree/tree-multimap.d.ts +12 -0
  82. package/dist/mjs/data-structures/binary-tree/tree-multimap.js +16 -0
  83. package/dist/mjs/data-structures/graph/abstract-graph.d.ts +44 -6
  84. package/dist/mjs/data-structures/graph/abstract-graph.js +52 -27
  85. package/dist/mjs/data-structures/hash/hash-map.d.ts +160 -44
  86. package/dist/mjs/data-structures/hash/hash-map.js +310 -80
  87. package/dist/mjs/data-structures/heap/heap.d.ts +50 -7
  88. package/dist/mjs/data-structures/heap/heap.js +60 -30
  89. package/dist/mjs/data-structures/index.d.ts +1 -0
  90. package/dist/mjs/data-structures/index.js +1 -0
  91. package/dist/mjs/data-structures/linked-list/doubly-linked-list.d.ts +38 -51
  92. package/dist/mjs/data-structures/linked-list/doubly-linked-list.js +46 -73
  93. package/dist/mjs/data-structures/linked-list/singly-linked-list.d.ts +32 -51
  94. package/dist/mjs/data-structures/linked-list/singly-linked-list.js +40 -73
  95. package/dist/mjs/data-structures/queue/deque.d.ts +29 -51
  96. package/dist/mjs/data-structures/queue/deque.js +36 -71
  97. package/dist/mjs/data-structures/queue/queue.d.ts +49 -48
  98. package/dist/mjs/data-structures/queue/queue.js +66 -79
  99. package/dist/mjs/data-structures/stack/stack.d.ts +43 -10
  100. package/dist/mjs/data-structures/stack/stack.js +50 -31
  101. package/dist/mjs/data-structures/trie/trie.d.ts +41 -6
  102. package/dist/mjs/data-structures/trie/trie.js +53 -32
  103. package/dist/mjs/types/data-structures/base/base.d.ts +5 -0
  104. package/dist/mjs/types/data-structures/base/base.js +1 -0
  105. package/dist/mjs/types/data-structures/base/index.d.ts +1 -0
  106. package/dist/mjs/types/data-structures/base/index.js +1 -0
  107. package/dist/mjs/types/data-structures/hash/hash-map.d.ts +4 -0
  108. package/dist/mjs/types/data-structures/index.d.ts +1 -0
  109. package/dist/mjs/types/data-structures/index.js +1 -0
  110. package/dist/umd/data-structure-typed.js +1104 -575
  111. package/dist/umd/data-structure-typed.min.js +2 -2
  112. package/dist/umd/data-structure-typed.min.js.map +1 -1
  113. package/package.json +2 -2
  114. package/src/data-structures/base/index.ts +1 -0
  115. package/src/data-structures/base/iterable-base.ts +329 -0
  116. package/src/data-structures/binary-tree/binary-tree.ts +98 -93
  117. package/src/data-structures/binary-tree/tree-multimap.ts +18 -0
  118. package/src/data-structures/graph/abstract-graph.ts +55 -28
  119. package/src/data-structures/hash/hash-map.ts +334 -83
  120. package/src/data-structures/heap/heap.ts +63 -36
  121. package/src/data-structures/index.ts +1 -0
  122. package/src/data-structures/linked-list/doubly-linked-list.ts +50 -79
  123. package/src/data-structures/linked-list/singly-linked-list.ts +45 -80
  124. package/src/data-structures/queue/deque.ts +40 -82
  125. package/src/data-structures/queue/queue.ts +72 -87
  126. package/src/data-structures/stack/stack.ts +53 -34
  127. package/src/data-structures/trie/trie.ts +58 -35
  128. package/src/types/data-structures/base/base.ts +6 -0
  129. package/src/types/data-structures/base/index.ts +1 -0
  130. package/src/types/data-structures/hash/hash-map.ts +2 -0
  131. package/src/types/data-structures/index.ts +1 -0
  132. package/test/integration/avl-tree.test.ts +2 -2
  133. package/test/integration/bst.test.ts +21 -25
  134. package/test/performance/data-structures/binary-tree/binary-tree.test.ts +17 -12
  135. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +24 -8
  136. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +24 -9
  137. package/test/unit/data-structures/binary-tree/bst.test.ts +24 -8
  138. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +8 -8
  139. package/test/unit/data-structures/binary-tree/tree-multimap.test.ts +82 -1
  140. package/test/unit/data-structures/graph/directed-graph.test.ts +4 -4
  141. package/test/unit/data-structures/hash/hash-map.test.ts +312 -18
  142. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +28 -0
  143. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +25 -0
  144. package/test/unit/data-structures/queue/deque.test.ts +25 -0
@@ -6,7 +6,226 @@
6
6
  * @license MIT License
7
7
  */
8
8
  import { isWeakKey, rangeCheck } from '../../utils';
9
- export class HashMap {
9
+ import { IterablePairBase } from "../base";
10
+ export class HashMap extends IterablePairBase {
11
+ _store = {};
12
+ _objMap = new Map();
13
+ /**
14
+ * The constructor function initializes a new instance of a class with optional elements and options.
15
+ * @param elements - The `elements` parameter is an iterable containing key-value pairs `[K, V]`. It
16
+ * is optional and defaults to an empty array `[]`. This parameter is used to initialize the map with
17
+ * key-value pairs.
18
+ * @param [options] - The `options` parameter is an optional object that can contain additional
19
+ * configuration options for the constructor. In this case, it has one property:
20
+ */
21
+ constructor(elements = [], options) {
22
+ super();
23
+ if (options) {
24
+ const { hashFn } = options;
25
+ if (hashFn) {
26
+ this._hashFn = hashFn;
27
+ }
28
+ }
29
+ if (elements) {
30
+ this.setMany(elements);
31
+ }
32
+ }
33
+ _size = 0;
34
+ get size() {
35
+ return this._size;
36
+ }
37
+ isEmpty() {
38
+ return this.size === 0;
39
+ }
40
+ clear() {
41
+ this._store = {};
42
+ this._objMap.clear();
43
+ this._size = 0;
44
+ }
45
+ /**
46
+ * The `set` function adds a key-value pair to a map-like data structure, incrementing the size if
47
+ * the key is not already present.
48
+ * @param {K} key - The key parameter is the key used to identify the value in the data structure. It
49
+ * can be of any type, but if it is an object, it will be stored in a Map, otherwise it will be
50
+ * stored in a regular JavaScript object.
51
+ * @param {V} value - The value parameter represents the value that you want to associate with the
52
+ * key in the data structure.
53
+ */
54
+ set(key, value) {
55
+ if (this._isObjKey(key)) {
56
+ if (!this._objMap.has(key)) {
57
+ this._size++;
58
+ }
59
+ this._objMap.set(key, value);
60
+ }
61
+ else {
62
+ const strKey = this._getNoObjKey(key);
63
+ if (this._store[strKey] === undefined) {
64
+ this._size++;
65
+ }
66
+ this._store[strKey] = { key, value };
67
+ }
68
+ }
69
+ /**
70
+ * The function "setMany" sets multiple key-value pairs in a map.
71
+ * @param elements - The `elements` parameter is an iterable containing key-value pairs. Each
72
+ * key-value pair is represented as an array with two elements: the key and the value.
73
+ */
74
+ setMany(elements) {
75
+ for (const [key, value] of elements)
76
+ this.set(key, value);
77
+ }
78
+ /**
79
+ * The `get` function retrieves a value from a map based on a given key, either from an object map or
80
+ * a string map.
81
+ * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be
82
+ * of any type, but it should be compatible with the key type used when the map was created.
83
+ * @returns The method `get(key: K)` returns a value of type `V` if the key exists in the `_objMap`
84
+ * or `_store`, otherwise it returns `undefined`.
85
+ */
86
+ get(key) {
87
+ if (this._isObjKey(key)) {
88
+ return this._objMap.get(key);
89
+ }
90
+ else {
91
+ const strKey = this._getNoObjKey(key);
92
+ return this._store[strKey]?.value;
93
+ }
94
+ }
95
+ /**
96
+ * The `has` function checks if a given key exists in the `_objMap` or `_store` based on whether it
97
+ * is an object key or not.
98
+ * @param {K} key - The parameter "key" is of type K, which means it can be any type.
99
+ * @returns The `has` method is returning a boolean value.
100
+ */
101
+ has(key) {
102
+ if (this._isObjKey(key)) {
103
+ return this._objMap.has(key);
104
+ }
105
+ else {
106
+ const strKey = this._getNoObjKey(key);
107
+ return strKey in this._store;
108
+ }
109
+ }
110
+ /**
111
+ * The `delete` function removes an element from a map-like data structure based on the provided key.
112
+ * @param {K} key - The `key` parameter is the key of the element that you want to delete from the
113
+ * data structure.
114
+ * @returns The `delete` method returns a boolean value. It returns `true` if the key was
115
+ * successfully deleted from the map, and `false` if the key was not found in the map.
116
+ */
117
+ delete(key) {
118
+ if (this._isObjKey(key)) {
119
+ if (this._objMap.has(key)) {
120
+ this._size--;
121
+ }
122
+ return this._objMap.delete(key);
123
+ }
124
+ else {
125
+ const strKey = this._getNoObjKey(key);
126
+ if (strKey in this._store) {
127
+ delete this._store[strKey];
128
+ this._size--;
129
+ return true;
130
+ }
131
+ return false;
132
+ }
133
+ }
134
+ /**
135
+ * Time Complexity: O(n)
136
+ * Space Complexity: O(n)
137
+ */
138
+ /**
139
+ * Time Complexity: O(n)
140
+ * Space Complexity: O(n)
141
+ *
142
+ * The `map` function in TypeScript creates a new HashMap by applying a callback function to each
143
+ * key-value pair in the original HashMap.
144
+ * @param callbackfn - The callback function that will be called for each key-value pair in the
145
+ * HashMap. It takes four parameters:
146
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
147
+ * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will
148
+ * be passed as the `this` value to the `callbackfn` function. If `thisArg
149
+ * @returns The `map` method is returning a new `HashMap` object with the transformed values based on
150
+ * the provided callback function.
151
+ */
152
+ map(callbackfn, thisArg) {
153
+ const resultMap = new HashMap();
154
+ let index = 0;
155
+ for (const [key, value] of this) {
156
+ resultMap.set(key, callbackfn.call(thisArg, value, key, index++, this));
157
+ }
158
+ return resultMap;
159
+ }
160
+ /**
161
+ * Time Complexity: O(n)
162
+ * Space Complexity: O(n)
163
+ */
164
+ /**
165
+ * Time Complexity: O(n)
166
+ * Space Complexity: O(n)
167
+ *
168
+ * The `filter` function creates a new HashMap containing key-value pairs from the original HashMap
169
+ * that satisfy a given predicate function.
170
+ * @param predicate - The predicate parameter is a function that takes four arguments: value, key,
171
+ * index, and map. It is used to determine whether an element should be included in the filtered map
172
+ * or not. The function should return a boolean value - true if the element should be included, and
173
+ * false otherwise.
174
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
175
+ * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be
176
+ * passed as the `this` value to the `predicate` function. If `thisArg` is
177
+ * @returns The `filter` method is returning a new `HashMap` object that contains the key-value pairs
178
+ * from the original `HashMap` that pass the provided `predicate` function.
179
+ */
180
+ filter(predicate, thisArg) {
181
+ const filteredMap = new HashMap();
182
+ let index = 0;
183
+ for (const [key, value] of this) {
184
+ if (predicate.call(thisArg, value, key, index++, this)) {
185
+ filteredMap.set(key, value);
186
+ }
187
+ }
188
+ return filteredMap;
189
+ }
190
+ print() {
191
+ console.log([...this.entries()]);
192
+ }
193
+ /**
194
+ * The function returns an iterator that yields key-value pairs from both an object store and an
195
+ * object map.
196
+ */
197
+ *_getIterator() {
198
+ for (const node of Object.values(this._store)) {
199
+ yield [node.key, node.value];
200
+ }
201
+ for (const node of this._objMap) {
202
+ yield node;
203
+ }
204
+ }
205
+ _hashFn = (key) => String(key);
206
+ _isObjKey(key) {
207
+ const keyType = typeof key;
208
+ return (keyType === 'object' || keyType === 'function') && key !== null;
209
+ }
210
+ _getNoObjKey(key) {
211
+ const keyType = typeof key;
212
+ let strKey;
213
+ if (keyType !== "string" && keyType !== "number" && keyType !== "symbol") {
214
+ strKey = this._hashFn(key);
215
+ }
216
+ else {
217
+ if (keyType === "number") {
218
+ // TODO numeric key should has its own hash
219
+ strKey = key;
220
+ }
221
+ else {
222
+ strKey = key;
223
+ }
224
+ }
225
+ return strKey;
226
+ }
227
+ }
228
+ export class LinkedHashMap extends IterablePairBase {
10
229
  _noObjMap = {};
11
230
  _objMap = new WeakMap();
12
231
  _head;
@@ -18,6 +237,7 @@ export class HashMap {
18
237
  hashFn: (key) => String(key),
19
238
  objHashFn: (key) => key
20
239
  }) {
240
+ super();
21
241
  this._sentinel = {};
22
242
  this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;
23
243
  const { hashFn, objHashFn } = options;
@@ -94,47 +314,62 @@ export class HashMap {
94
314
  */
95
315
  set(key, value) {
96
316
  let node;
317
+ const isNewKey = !this.has(key); // Check if the key is new
97
318
  if (isWeakKey(key)) {
98
319
  const hash = this._objHashFn(key);
99
320
  node = this._objMap.get(hash);
100
- if (node) {
101
- // If the node already exists, update its value
102
- node.value = value;
103
- }
104
- else {
321
+ if (!node && isNewKey) {
105
322
  // Create new node
106
323
  node = { key: hash, value, prev: this._tail, next: this._sentinel };
107
- // Add new nodes to _objMap and linked list
108
324
  this._objMap.set(hash, node);
109
325
  }
326
+ else if (node) {
327
+ // Update the value of an existing node
328
+ node.value = value;
329
+ }
110
330
  }
111
331
  else {
112
332
  const hash = this._hashFn(key);
113
- // Non-object keys are handled in the same way as the original implementation
114
333
  node = this._noObjMap[hash];
115
- if (node) {
334
+ if (!node && isNewKey) {
335
+ this._noObjMap[hash] = node = { key, value, prev: this._tail, next: this._sentinel };
336
+ }
337
+ else if (node) {
338
+ // Update the value of an existing node
116
339
  node.value = value;
117
340
  }
341
+ }
342
+ if (node && isNewKey) {
343
+ // Update the head and tail of the linked list
344
+ if (this._size === 0) {
345
+ this._head = node;
346
+ this._sentinel.next = node;
347
+ }
118
348
  else {
119
- this._noObjMap[hash] = node = {
120
- key,
121
- value,
122
- prev: this._tail,
123
- next: this._sentinel
124
- };
349
+ this._tail.next = node;
350
+ node.prev = this._tail; // Make sure that the prev of the new node points to the current tail node
125
351
  }
352
+ this._tail = node;
353
+ this._sentinel.prev = node;
354
+ this._size++;
126
355
  }
127
- if (this._size === 0) {
128
- this._head = node;
129
- this._sentinel.next = node;
356
+ return this._size;
357
+ }
358
+ has(key) {
359
+ if (isWeakKey(key)) {
360
+ const hash = this._objHashFn(key);
361
+ return this._objMap.has(hash);
130
362
  }
131
363
  else {
132
- this._tail.next = node;
364
+ const hash = this._hashFn(key);
365
+ return hash in this._noObjMap;
366
+ }
367
+ }
368
+ setMany(entries) {
369
+ for (const entry of entries) {
370
+ const [key, value] = entry;
371
+ this.set(key, value);
133
372
  }
134
- this._tail = node;
135
- this._sentinel.prev = node;
136
- this._size++;
137
- return this._size;
138
373
  }
139
374
  /**
140
375
  * Time Complexity: O(1)
@@ -256,36 +491,38 @@ export class HashMap {
256
491
  this._size = 0;
257
492
  this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;
258
493
  }
259
- /**
260
- * Time Complexity: O(n), where n is the number of elements in the HashMap.
261
- * Space Complexity: O(1)
262
- *
263
- * The `forEach` function iterates over each element in a HashMap and executes a callback function on
264
- * each element.
265
- * @param callback - The callback parameter is a function that will be called for each element in the
266
- * HashMap. It takes three arguments:
267
- */
268
- forEach(callback) {
269
- let index = 0;
270
- let node = this._head;
271
- while (node !== this._sentinel) {
272
- callback([node.key, node.value], index++, this);
273
- node = node.next;
494
+ clone() {
495
+ const cloned = new LinkedHashMap([], { hashFn: this._hashFn, objHashFn: this._objHashFn });
496
+ for (const entry of this) {
497
+ const [key, value] = entry;
498
+ cloned.set(key, value);
274
499
  }
500
+ return cloned;
275
501
  }
276
502
  /**
277
- * The `filter` function takes a predicate function and returns a new HashMap containing only the
278
- * key-value pairs that satisfy the predicate.
279
- * @param predicate - The `predicate` parameter is a function that takes two arguments: `element` and
280
- * `map`.
281
- * @returns a new HashMap object that contains the key-value pairs from the original HashMap that
282
- * satisfy the given predicate function.
503
+ * Time Complexity: O(n)
504
+ * Space Complexity: O(n)
283
505
  */
284
- filter(predicate) {
285
- const filteredMap = new HashMap();
506
+ /**
507
+ * Time Complexity: O(n)
508
+ * Space Complexity: O(n)
509
+ *
510
+ * The `filter` function creates a new `LinkedHashMap` containing key-value pairs from the original
511
+ * map that satisfy a given predicate function.
512
+ * @param predicate - The `predicate` parameter is a callback function that takes four arguments:
513
+ * `value`, `key`, `index`, and `this`. It should return a boolean value indicating whether the
514
+ * current element should be included in the filtered map or not.
515
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
516
+ * specify the value of `this` within the `predicate` function. It is used when you want to bind a
517
+ * specific object as the context for the `predicate` function. If `thisArg` is not provided, `this
518
+ * @returns a new `LinkedHashMap` object that contains the key-value pairs from the original
519
+ * `LinkedHashMap` object that satisfy the given predicate function.
520
+ */
521
+ filter(predicate, thisArg) {
522
+ const filteredMap = new LinkedHashMap();
286
523
  let index = 0;
287
524
  for (const [key, value] of this) {
288
- if (predicate([key, value], index, this)) {
525
+ if (predicate.call(thisArg, value, key, index, this)) {
289
526
  filteredMap.set(key, value);
290
527
  }
291
528
  index++;
@@ -293,59 +530,52 @@ export class HashMap {
293
530
  return filteredMap;
294
531
  }
295
532
  /**
296
- * The `map` function takes a callback function and returns a new HashMap with the values transformed
297
- * by the callback.
298
- * @param callback - The `callback` parameter is a function that takes two arguments: `element` and
299
- * `map`.
300
- * @returns a new HashMap object with the values mapped according to the provided callback function.
533
+ * Time Complexity: O(n)
534
+ * Space Complexity: O(n)
535
+ */
536
+ /**
537
+ * Time Complexity: O(n)
538
+ * Space Complexity: O(n)
539
+ *
540
+ * The `map` function in TypeScript creates a new `LinkedHashMap` by applying a callback function to
541
+ * each key-value pair in the original map.
542
+ * @param callback - The callback parameter is a function that will be called for each key-value pair
543
+ * in the map. It takes four arguments: the value of the current key-value pair, the key of the
544
+ * current key-value pair, the index of the current key-value pair, and the map itself. The callback
545
+ * function should
546
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
547
+ * specify the value of `this` within the callback function. If provided, the callback function will
548
+ * be called with `thisArg` as its `this` value. If not provided, `this` will refer to the current
549
+ * map
550
+ * @returns a new `LinkedHashMap` object with the values mapped according to the provided callback
551
+ * function.
301
552
  */
302
- map(callback) {
303
- const mappedMap = new HashMap();
553
+ map(callback, thisArg) {
554
+ const mappedMap = new LinkedHashMap();
304
555
  let index = 0;
305
556
  for (const [key, value] of this) {
306
- const newValue = callback([key, value], index, this);
557
+ const newValue = callback.call(thisArg, value, key, index, this);
307
558
  mappedMap.set(key, newValue);
308
559
  index++;
309
560
  }
310
561
  return mappedMap;
311
562
  }
312
- /**
313
- * The `reduce` function iterates over the elements of a HashMap and applies a callback function to
314
- * each element, accumulating a single value.
315
- * @param callback - The callback parameter is a function that takes three arguments: accumulator,
316
- * element, and map. It is called for each element in the HashMap and is used to accumulate a single
317
- * result.
318
- * @param {A} initialValue - The `initialValue` parameter is the initial value of the accumulator. It
319
- * is the value that will be passed as the first argument to the `callback` function when reducing
320
- * the elements of the map.
321
- * @returns The `reduce` function is returning the final value of the accumulator after iterating
322
- * over all the elements in the HashMap and applying the callback function to each element.
323
- */
324
- reduce(callback, initialValue) {
325
- let accumulator = initialValue;
326
- let index = 0;
327
- for (const entry of this) {
328
- accumulator = callback(accumulator, entry, index, this);
329
- index++;
330
- }
331
- return accumulator;
563
+ print() {
564
+ console.log([...this]);
332
565
  }
333
566
  /**
334
- * Time Complexity: O(n), where n is the number of elements in the HashMap.
567
+ * Time Complexity: O(n), where n is the number of elements in the LinkedHashMap.
335
568
  * Space Complexity: O(1)
336
569
  *
337
570
  * The above function is an iterator that yields key-value pairs from a linked list.
338
571
  */
339
- *[Symbol.iterator]() {
572
+ *_getIterator() {
340
573
  let node = this._head;
341
574
  while (node !== this._sentinel) {
342
575
  yield [node.key, node.value];
343
576
  node = node.next;
344
577
  }
345
578
  }
346
- print() {
347
- console.log([...this]);
348
- }
349
579
  /**
350
580
  * Time Complexity: O(1)
351
581
  * Space Complexity: O(1)
@@ -4,9 +4,10 @@
4
4
  * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>
5
5
  * @license MIT License
6
6
  */
7
- import type { Comparator, DFSOrderPattern } from '../../types';
7
+ import type { Comparator, DFSOrderPattern, ElementCallback } from '../../types';
8
8
  import { HeapOptions } from "../../types";
9
- export declare class Heap<E = any> {
9
+ import { IterableElementBase } from "../base";
10
+ export declare class Heap<E = any> extends IterableElementBase<E> {
10
11
  options: HeapOptions<E>;
11
12
  constructor(elements?: Iterable<E>, options?: HeapOptions<E>);
12
13
  protected _elements: E[];
@@ -192,16 +193,58 @@ export declare class Heap<E = any> {
192
193
  * Fix the entire heap to maintain heap properties.
193
194
  */
194
195
  fix(): void;
195
- [Symbol.iterator](): Generator<E, void, unknown>;
196
- forEach(callback: (element: E, index: number, heap: this) => void): void;
197
- filter(predicate: (element: E, index: number, heap: Heap<E>) => boolean): Heap<E>;
198
- map<T>(callback: (element: E, index: number, heap: Heap<E>) => T, comparator: Comparator<T>): Heap<T>;
199
- reduce<T>(callback: (accumulator: T, currentValue: E, currentIndex: number, heap: Heap<E>) => T, initialValue: T): T;
196
+ /**
197
+ * Time Complexity: O(n)
198
+ * Space Complexity: O(n)
199
+ */
200
+ /**
201
+ * Time Complexity: O(n)
202
+ * Space Complexity: O(n)
203
+ *
204
+ * The `filter` function creates a new Heap object containing elements that pass a given callback
205
+ * function.
206
+ * @param callback - The `callback` parameter is a function that will be called for each element in
207
+ * the heap. It takes three arguments: the current element, the index of the current element, and the
208
+ * heap itself. The callback function should return a boolean value indicating whether the current
209
+ * element should be included in the filtered list
210
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
211
+ * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be
212
+ * passed as the `this` value to the `callback` function. If `thisArg` is
213
+ * @returns The `filter` method is returning a new `Heap` object that contains the elements that pass
214
+ * the filter condition specified by the `callback` function.
215
+ */
216
+ filter(callback: ElementCallback<E, boolean>, thisArg?: any): Heap<E>;
217
+ /**
218
+ * Time Complexity: O(n)
219
+ * Space Complexity: O(n)
220
+ */
221
+ /**
222
+ * Time Complexity: O(n)
223
+ * Space Complexity: O(n)
224
+ *
225
+ * The `map` function creates a new heap by applying a callback function to each element of the
226
+ * original heap.
227
+ * @param callback - The callback parameter is a function that will be called for each element in the
228
+ * original heap. It takes three arguments: the current element, the index of the current element,
229
+ * and the original heap itself. The callback function should return a value of type T, which will be
230
+ * added to the mapped heap.
231
+ * @param comparator - The `comparator` parameter is a function that is used to compare elements in
232
+ * the heap. It takes two arguments, `a` and `b`, and returns a negative number if `a` is less than
233
+ * `b`, a positive number if `a` is greater than `b`, or
234
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
235
+ * specify the value of `this` within the callback function. It is used when you want to bind a
236
+ * specific object as the context for the callback function. If `thisArg` is not provided,
237
+ * `undefined` is used as
238
+ * @returns a new instance of the Heap class, which is created using the mapped elements from the
239
+ * original Heap.
240
+ */
241
+ map<T>(callback: ElementCallback<E, T>, comparator: Comparator<T>, thisArg?: any): Heap<T>;
200
242
  /**
201
243
  * Time Complexity: O(log n)
202
244
  * Space Complexity: O(1)
203
245
  */
204
246
  print(): void;
247
+ protected _getIterator(): Generator<E, void, unknown>;
205
248
  /**
206
249
  * Time Complexity: O(n)
207
250
  * Space Complexity: O(1)
@@ -4,9 +4,11 @@
4
4
  * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>
5
5
  * @license MIT License
6
6
  */
7
- export class Heap {
7
+ import { IterableElementBase } from "../base";
8
+ export class Heap extends IterableElementBase {
8
9
  options;
9
10
  constructor(elements, options) {
11
+ super();
10
12
  const defaultComparator = (a, b) => {
11
13
  if (!(typeof a === 'number' && typeof b === 'number')) {
12
14
  throw new Error('The a, b params of compare function must be number');
@@ -307,47 +309,70 @@ export class Heap {
307
309
  for (let i = Math.floor(this.size / 2); i >= 0; i--)
308
310
  this._sinkDown(i, this.elements.length >> 1);
309
311
  }
310
- *[Symbol.iterator]() {
311
- for (const element of this.elements) {
312
- yield element;
313
- }
314
- }
315
- forEach(callback) {
316
- let index = 0;
317
- for (const el of this) {
318
- callback(el, index, this);
319
- index++;
320
- }
321
- }
322
- filter(predicate) {
323
- const filteredHeap = new Heap([], this.options);
312
+ /**
313
+ * Time Complexity: O(n)
314
+ * Space Complexity: O(n)
315
+ */
316
+ /**
317
+ * Time Complexity: O(n)
318
+ * Space Complexity: O(n)
319
+ *
320
+ * The `filter` function creates a new Heap object containing elements that pass a given callback
321
+ * function.
322
+ * @param callback - The `callback` parameter is a function that will be called for each element in
323
+ * the heap. It takes three arguments: the current element, the index of the current element, and the
324
+ * heap itself. The callback function should return a boolean value indicating whether the current
325
+ * element should be included in the filtered list
326
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
327
+ * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be
328
+ * passed as the `this` value to the `callback` function. If `thisArg` is
329
+ * @returns The `filter` method is returning a new `Heap` object that contains the elements that pass
330
+ * the filter condition specified by the `callback` function.
331
+ */
332
+ filter(callback, thisArg) {
333
+ const filteredList = new Heap();
324
334
  let index = 0;
325
- for (const el of this) {
326
- if (predicate(el, index, this)) {
327
- filteredHeap.push(el);
335
+ for (const current of this) {
336
+ if (callback.call(thisArg, current, index, this)) {
337
+ filteredList.push(current);
328
338
  }
329
339
  index++;
330
340
  }
331
- return filteredHeap;
341
+ return filteredList;
332
342
  }
333
- map(callback, comparator) {
343
+ /**
344
+ * Time Complexity: O(n)
345
+ * Space Complexity: O(n)
346
+ */
347
+ /**
348
+ * Time Complexity: O(n)
349
+ * Space Complexity: O(n)
350
+ *
351
+ * The `map` function creates a new heap by applying a callback function to each element of the
352
+ * original heap.
353
+ * @param callback - The callback parameter is a function that will be called for each element in the
354
+ * original heap. It takes three arguments: the current element, the index of the current element,
355
+ * and the original heap itself. The callback function should return a value of type T, which will be
356
+ * added to the mapped heap.
357
+ * @param comparator - The `comparator` parameter is a function that is used to compare elements in
358
+ * the heap. It takes two arguments, `a` and `b`, and returns a negative number if `a` is less than
359
+ * `b`, a positive number if `a` is greater than `b`, or
360
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
361
+ * specify the value of `this` within the callback function. It is used when you want to bind a
362
+ * specific object as the context for the callback function. If `thisArg` is not provided,
363
+ * `undefined` is used as
364
+ * @returns a new instance of the Heap class, which is created using the mapped elements from the
365
+ * original Heap.
366
+ */
367
+ map(callback, comparator, thisArg) {
334
368
  const mappedHeap = new Heap([], { comparator: comparator });
335
369
  let index = 0;
336
370
  for (const el of this) {
337
- mappedHeap.add(callback(el, index, this));
371
+ mappedHeap.add(callback.call(thisArg, el, index, this));
338
372
  index++;
339
373
  }
340
374
  return mappedHeap;
341
375
  }
342
- reduce(callback, initialValue) {
343
- let accumulator = initialValue;
344
- let index = 0;
345
- for (const el of this) {
346
- accumulator = callback(accumulator, el, index, this);
347
- index++;
348
- }
349
- return accumulator;
350
- }
351
376
  /**
352
377
  * Time Complexity: O(log n)
353
378
  * Space Complexity: O(1)
@@ -355,6 +380,11 @@ export class Heap {
355
380
  print() {
356
381
  console.log([...this]);
357
382
  }
383
+ *_getIterator() {
384
+ for (const element of this.elements) {
385
+ yield element;
386
+ }
387
+ }
358
388
  /**
359
389
  * Time Complexity: O(n)
360
390
  * 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';
@@ -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';