min-heap-typed 1.50.1 → 1.50.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 (85) hide show
  1. package/dist/data-structures/base/iterable-base.d.ts +120 -9
  2. package/dist/data-structures/base/iterable-base.js +143 -7
  3. package/dist/data-structures/binary-tree/avl-tree.d.ts +72 -47
  4. package/dist/data-structures/binary-tree/avl-tree.js +101 -72
  5. package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +22 -0
  6. package/dist/data-structures/binary-tree/binary-indexed-tree.js +22 -0
  7. package/dist/data-structures/binary-tree/binary-tree.d.ts +244 -199
  8. package/dist/data-structures/binary-tree/binary-tree.js +484 -376
  9. package/dist/data-structures/binary-tree/bst.d.ts +92 -79
  10. package/dist/data-structures/binary-tree/bst.js +68 -76
  11. package/dist/data-structures/binary-tree/rb-tree.d.ts +127 -57
  12. package/dist/data-structures/binary-tree/rb-tree.js +152 -99
  13. package/dist/data-structures/binary-tree/segment-tree.d.ts +99 -6
  14. package/dist/data-structures/binary-tree/segment-tree.js +127 -10
  15. package/dist/data-structures/binary-tree/tree-multimap.d.ts +72 -58
  16. package/dist/data-structures/binary-tree/tree-multimap.js +102 -85
  17. package/dist/data-structures/graph/abstract-graph.d.ts +1 -78
  18. package/dist/data-structures/graph/abstract-graph.js +3 -189
  19. package/dist/data-structures/graph/directed-graph.d.ts +73 -0
  20. package/dist/data-structures/graph/directed-graph.js +131 -0
  21. package/dist/data-structures/graph/map-graph.d.ts +8 -0
  22. package/dist/data-structures/graph/map-graph.js +14 -0
  23. package/dist/data-structures/graph/undirected-graph.d.ts +76 -7
  24. package/dist/data-structures/graph/undirected-graph.js +151 -18
  25. package/dist/data-structures/hash/hash-map.d.ts +254 -28
  26. package/dist/data-structures/hash/hash-map.js +347 -78
  27. package/dist/data-structures/heap/heap.d.ts +95 -25
  28. package/dist/data-structures/heap/heap.js +95 -26
  29. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +126 -63
  30. package/dist/data-structures/linked-list/doubly-linked-list.js +141 -77
  31. package/dist/data-structures/linked-list/singly-linked-list.d.ts +154 -106
  32. package/dist/data-structures/linked-list/singly-linked-list.js +164 -115
  33. package/dist/data-structures/linked-list/skip-linked-list.d.ts +63 -36
  34. package/dist/data-structures/linked-list/skip-linked-list.js +63 -36
  35. package/dist/data-structures/matrix/matrix.d.ts +35 -4
  36. package/dist/data-structures/matrix/matrix.js +50 -11
  37. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +10 -0
  38. package/dist/data-structures/priority-queue/max-priority-queue.js +10 -0
  39. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -0
  40. package/dist/data-structures/priority-queue/min-priority-queue.js +11 -0
  41. package/dist/data-structures/priority-queue/priority-queue.d.ts +8 -0
  42. package/dist/data-structures/priority-queue/priority-queue.js +8 -0
  43. package/dist/data-structures/queue/deque.d.ts +139 -35
  44. package/dist/data-structures/queue/deque.js +200 -62
  45. package/dist/data-structures/queue/queue.d.ts +103 -49
  46. package/dist/data-structures/queue/queue.js +111 -49
  47. package/dist/data-structures/stack/stack.d.ts +51 -21
  48. package/dist/data-structures/stack/stack.js +58 -22
  49. package/dist/data-structures/tree/tree.d.ts +57 -3
  50. package/dist/data-structures/tree/tree.js +77 -11
  51. package/dist/data-structures/trie/trie.d.ts +135 -34
  52. package/dist/data-structures/trie/trie.js +153 -33
  53. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  54. package/dist/types/data-structures/hash/hash-map.d.ts +4 -3
  55. package/dist/types/utils/utils.d.ts +1 -0
  56. package/package.json +2 -2
  57. package/src/data-structures/base/iterable-base.ts +184 -19
  58. package/src/data-structures/binary-tree/avl-tree.ts +134 -100
  59. package/src/data-structures/binary-tree/binary-indexed-tree.ts +22 -0
  60. package/src/data-structures/binary-tree/binary-tree.ts +674 -671
  61. package/src/data-structures/binary-tree/bst.ts +127 -136
  62. package/src/data-structures/binary-tree/rb-tree.ts +199 -166
  63. package/src/data-structures/binary-tree/segment-tree.ts +145 -11
  64. package/src/data-structures/binary-tree/tree-multimap.ts +138 -115
  65. package/src/data-structures/graph/abstract-graph.ts +4 -211
  66. package/src/data-structures/graph/directed-graph.ts +152 -0
  67. package/src/data-structures/graph/map-graph.ts +15 -0
  68. package/src/data-structures/graph/undirected-graph.ts +171 -19
  69. package/src/data-structures/hash/hash-map.ts +389 -96
  70. package/src/data-structures/heap/heap.ts +97 -26
  71. package/src/data-structures/linked-list/doubly-linked-list.ts +156 -83
  72. package/src/data-structures/linked-list/singly-linked-list.ts +174 -120
  73. package/src/data-structures/linked-list/skip-linked-list.ts +63 -37
  74. package/src/data-structures/matrix/matrix.ts +52 -12
  75. package/src/data-structures/priority-queue/max-priority-queue.ts +10 -0
  76. package/src/data-structures/priority-queue/min-priority-queue.ts +11 -0
  77. package/src/data-structures/priority-queue/priority-queue.ts +8 -0
  78. package/src/data-structures/queue/deque.ts +225 -70
  79. package/src/data-structures/queue/queue.ts +118 -49
  80. package/src/data-structures/stack/stack.ts +63 -23
  81. package/src/data-structures/tree/tree.ts +89 -15
  82. package/src/data-structures/trie/trie.ts +173 -38
  83. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  84. package/src/types/data-structures/hash/hash-map.ts +4 -3
  85. package/src/types/utils/utils.ts +2 -0
@@ -22,9 +22,6 @@ import { isWeakKey, rangeCheck } from '../../utils';
22
22
  * 4. Unordered Collection: HashMap does not guarantee the order of entries, and the order may change over time.
23
23
  */
24
24
  export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {
25
- protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};
26
- protected _objMap: Map<object, V> = new Map();
27
-
28
25
  /**
29
26
  * The constructor function initializes a HashMap object with an optional initial collection and
30
27
  * options.
@@ -32,7 +29,7 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
32
29
  * `T`. It is an optional parameter and its default value is an empty array `[]`.
33
30
  * @param [options] - The `options` parameter is an optional object that can contain two properties:
34
31
  */
35
- constructor(rawCollection: Iterable<R> = [], options?: HashMapOptions<K, V, R>) {
32
+ constructor(rawCollection: Iterable<R | [K, V]> = [], options?: HashMapOptions<K, V, R>) {
36
33
  super();
37
34
  if (options) {
38
35
  const { hashFn, toEntryFn } = options;
@@ -48,6 +45,28 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
48
45
  }
49
46
  }
50
47
 
48
+ protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};
49
+
50
+ /**
51
+ * The function returns the store object, which is a dictionary of HashMapStoreItem objects.
52
+ * @returns The store property is being returned. It is a dictionary-like object with string keys and
53
+ * values of type HashMapStoreItem<K, V>.
54
+ */
55
+ get store(): { [p: string]: HashMapStoreItem<K, V> } {
56
+ return this._store;
57
+ }
58
+
59
+ protected _objMap: Map<object, V> = new Map();
60
+
61
+ /**
62
+ * The function returns the object map.
63
+ * @returns The `objMap` property is being returned, which is a `Map` object with keys of type
64
+ * `object` and values of type `V`.
65
+ */
66
+ get objMap(): Map<object, V> {
67
+ return this._objMap;
68
+ }
69
+
51
70
  protected _toEntryFn: (rawElement: R) => [K, V] = (rawElement: R) => {
52
71
  if (this.isEntry(rawElement)) {
53
72
  // TODO, For performance optimization, it may be necessary to only inspect the first element traversed.
@@ -59,24 +78,58 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
59
78
  }
60
79
  };
61
80
 
81
+ /**
82
+ * The function returns the value of the _toEntryFn property.
83
+ * @returns The function being returned is `this._toEntryFn`.
84
+ */
62
85
  get toEntryFn() {
63
86
  return this._toEntryFn;
64
87
  }
65
88
 
66
89
  protected _size = 0;
67
90
 
91
+ /**
92
+ * The function returns the size of an object.
93
+ * @returns The size of the object, which is a number.
94
+ */
68
95
  get size(): number {
69
96
  return this._size;
70
97
  }
71
98
 
99
+ protected _hashFn: (key: K) => string = (key: K) => String(key);
100
+
101
+ /**
102
+ * The hasFn function is a function that takes in an item and returns a boolean
103
+ * indicating whether the item is contained within the hash table.
104
+ *
105
+ * @return The hash function
106
+ */
107
+ get hashFn() {
108
+ return this._hashFn;
109
+ }
110
+
111
+ /**
112
+ * The function checks if a given element is an array with exactly two elements.
113
+ * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any
114
+ * data type.
115
+ * @returns a boolean value.
116
+ */
72
117
  isEntry(rawElement: any): rawElement is [K, V] {
73
118
  return Array.isArray(rawElement) && rawElement.length === 2;
74
119
  }
75
120
 
121
+ /**
122
+ * The function checks if the size of an object is equal to zero and returns a boolean value.
123
+ * @returns A boolean value indicating whether the size of the object is 0 or not.
124
+ */
76
125
  isEmpty(): boolean {
77
126
  return this.size === 0;
78
127
  }
79
128
 
129
+ /**
130
+ * The clear() function resets the state of an object by clearing its internal store, object map, and
131
+ * size.
132
+ */
80
133
  clear() {
81
134
  this._store = {};
82
135
  this._objMap.clear();
@@ -94,13 +147,13 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
94
147
  */
95
148
  set(key: K, value: V): boolean {
96
149
  if (this._isObjKey(key)) {
97
- if (!this._objMap.has(key)) {
150
+ if (!this.objMap.has(key)) {
98
151
  this._size++;
99
152
  }
100
- this._objMap.set(key, value);
153
+ this.objMap.set(key, value);
101
154
  } else {
102
155
  const strKey = this._getNoObjKey(key);
103
- if (this._store[strKey] === undefined) {
156
+ if (this.store[strKey] === undefined) {
104
157
  this._size++;
105
158
  }
106
159
  this._store[strKey] = { key, value };
@@ -115,10 +168,18 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
115
168
  * `T`.
116
169
  * @returns The `setMany` function is returning an array of booleans.
117
170
  */
118
- setMany(rawCollection: Iterable<R>): boolean[] {
171
+ setMany(rawCollection: Iterable<R | [K, V]>): boolean[] {
119
172
  const results: boolean[] = [];
120
173
  for (const rawEle of rawCollection) {
121
- const [key, value] = this.toEntryFn(rawEle);
174
+ let key, value;
175
+ if (this.isEntry(rawEle)) {
176
+ key = rawEle[0];
177
+ value = rawEle[1];
178
+ } else {
179
+ const item = this.toEntryFn(rawEle);
180
+ key = item[0];
181
+ value = item[1];
182
+ }
122
183
  results.push(this.set(key, value));
123
184
  }
124
185
  return results;
@@ -132,9 +193,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
132
193
  * @returns The method `get(key: K)` returns a value of type `V` if the key exists in the `_objMap`
133
194
  * or `_store`, otherwise it returns `undefined`.
134
195
  */
135
- get(key: K): V | undefined {
196
+ override get(key: K): V | undefined {
136
197
  if (this._isObjKey(key)) {
137
- return this._objMap.get(key);
198
+ return this.objMap.get(key);
138
199
  } else {
139
200
  const strKey = this._getNoObjKey(key);
140
201
  return this._store[strKey]?.value;
@@ -147,12 +208,12 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
147
208
  * @param {K} key - The parameter "key" is of type K, which means it can be any type.
148
209
  * @returns The `has` method is returning a boolean value.
149
210
  */
150
- has(key: K): boolean {
211
+ override has(key: K): boolean {
151
212
  if (this._isObjKey(key)) {
152
- return this._objMap.has(key);
213
+ return this.objMap.has(key);
153
214
  } else {
154
215
  const strKey = this._getNoObjKey(key);
155
- return strKey in this._store;
216
+ return strKey in this.store;
156
217
  }
157
218
  }
158
219
 
@@ -165,15 +226,15 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
165
226
  */
166
227
  delete(key: K): boolean {
167
228
  if (this._isObjKey(key)) {
168
- if (this._objMap.has(key)) {
229
+ if (this.objMap.has(key)) {
169
230
  this._size--;
170
231
  }
171
232
 
172
- return this._objMap.delete(key);
233
+ return this.objMap.delete(key);
173
234
  } else {
174
235
  const strKey = this._getNoObjKey(key);
175
- if (strKey in this._store) {
176
- delete this._store[strKey];
236
+ if (strKey in this.store) {
237
+ delete this.store[strKey];
177
238
  this._size--;
178
239
  return true;
179
240
  }
@@ -181,6 +242,22 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
181
242
  }
182
243
  }
183
244
 
245
+ /**
246
+ * Time Complexity: O(n)
247
+ * Space Complexity: O(n)
248
+ */
249
+
250
+ /**
251
+ * The clone function creates a new HashMap with the same key-value pairs as
252
+ * this one. The clone function is useful for creating a copy of an existing
253
+ * HashMap, and then modifying that copy without affecting the original.
254
+ *
255
+ * @return A new hashmap with the same values as this one
256
+ */
257
+ clone(): HashMap<K, V, R> {
258
+ return new HashMap<K, V, R>(this, { hashFn: this.hashFn, toEntryFn: this.toEntryFn });
259
+ }
260
+
184
261
  /**
185
262
  * Time Complexity: O(n)
186
263
  * Space Complexity: O(n)
@@ -209,11 +286,6 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
209
286
  return resultMap;
210
287
  }
211
288
 
212
- /**
213
- * Time Complexity: O(n)
214
- * Space Complexity: O(n)
215
- */
216
-
217
289
  /**
218
290
  * Time Complexity: O(n)
219
291
  * Space Complexity: O(n)
@@ -241,6 +313,14 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
241
313
  return filteredMap;
242
314
  }
243
315
 
316
+ /**
317
+ * The put function sets a value in a data structure using a specified key.
318
+ * @param {K} key - The key parameter is of type K, which represents the type of the key being passed
319
+ * to the function.
320
+ * @param {V} value - The value parameter represents the value that you want to associate with the
321
+ * specified key in the data structure.
322
+ * @returns The method is returning a boolean value.
323
+ */
244
324
  put(key: K, value: V): boolean {
245
325
  return this.set(key, value);
246
326
  }
@@ -250,27 +330,37 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
250
330
  * object map.
251
331
  */
252
332
  protected* _getIterator(): IterableIterator<[K, V]> {
253
- for (const node of Object.values(this._store)) {
333
+ for (const node of Object.values(this.store)) {
254
334
  yield [node.key, node.value] as [K, V];
255
335
  }
256
- for (const node of this._objMap) {
336
+ for (const node of this.objMap) {
257
337
  yield node as [K, V];
258
338
  }
259
339
  }
260
340
 
261
- protected _hashFn: (key: K) => string = (key: K) => String(key);
262
-
341
+ /**
342
+ * The function checks if a given key is an object or a function.
343
+ * @param {any} key - The parameter "key" can be of any type.
344
+ * @returns a boolean value.
345
+ */
263
346
  protected _isObjKey(key: any): key is object | ((...args: any[]) => any) {
264
347
  const keyType = typeof key;
265
348
  return (keyType === 'object' || keyType === 'function') && key !== null;
266
349
  }
267
350
 
351
+ /**
352
+ * The function `_getNoObjKey` takes a key and returns a string representation of the key, handling
353
+ * different types of keys.
354
+ * @param {K} key - The `key` parameter is of type `K`, which represents the type of the key being
355
+ * passed to the `_getNoObjKey` function.
356
+ * @returns a string value.
357
+ */
268
358
  protected _getNoObjKey(key: K): string {
269
359
  const keyType = typeof key;
270
360
 
271
361
  let strKey: string;
272
362
  if (keyType !== 'string' && keyType !== 'number' && keyType !== 'symbol') {
273
- strKey = this._hashFn(key);
363
+ strKey = this.hashFn(key);
274
364
  } else {
275
365
  if (keyType === 'number') {
276
366
  // TODO numeric key should has its own hash
@@ -288,37 +378,138 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
288
378
  * 2. Based on Hash Table and Linked List: It combines the structures of a hash table and a linked list, using the hash table to ensure fast access, while maintaining the order of entries through the linked list.
289
379
  * 3. Time Complexity: Similar to HashMap, LinkedHashMap offers constant-time performance for get and put operations in most cases.
290
380
  */
291
- export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
292
- protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};
293
- protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();
294
- protected _head: HashMapLinkedNode<K, V | undefined>;
295
- protected _tail: HashMapLinkedNode<K, V | undefined>;
381
+ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {
296
382
  protected readonly _sentinel: HashMapLinkedNode<K, V | undefined>;
297
383
 
298
- constructor(entries?: Iterable<[K, V]>, options?: LinkedHashMapOptions<K>) {
384
+ /**
385
+ * The constructor initializes a LinkedHashMap object with an optional raw collection and options.
386
+ * @param rawCollection - The `rawCollection` parameter is an iterable collection of elements. It is
387
+ * used to initialize the HashMapLinked instance with key-value pairs. Each element in the
388
+ * `rawCollection` is converted to a key-value pair using the `toEntryFn` function (if provided) and
389
+ * then added to the HashMap
390
+ * @param [options] - The `options` parameter is an optional object that can contain the following
391
+ * properties:
392
+ */
393
+ constructor(rawCollection: Iterable<R> = [], options?: LinkedHashMapOptions<K, V, R>) {
299
394
  super();
300
395
  this._sentinel = <HashMapLinkedNode<K, V>>{};
301
396
  this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;
302
397
 
303
398
  if (options) {
304
- const { hashFn, objHashFn } = options;
399
+ const { hashFn, objHashFn, toEntryFn } = options;
305
400
  if (hashFn) this._hashFn = hashFn;
306
401
  if (objHashFn) this._objHashFn = objHashFn;
402
+
403
+ if (toEntryFn) {
404
+ this._toEntryFn = toEntryFn;
405
+ }
307
406
  }
308
407
 
309
- if (entries) {
310
- for (const el of entries) {
311
- this.set(el[0], el[1]);
408
+ if (rawCollection) {
409
+ for (const el of rawCollection) {
410
+ const [key, value] = this.toEntryFn(el);
411
+ this.set(key, value);
312
412
  }
313
413
  }
314
414
  }
315
415
 
416
+ protected _hashFn: (key: K) => string = (key: K) => String(key);
417
+
418
+ /**
419
+ * The function returns the hash function used for generating a hash value for a given key.
420
+ * @returns The hash function that takes a key of type K and returns a string.
421
+ */
422
+ get hashFn(): (key: K) => string {
423
+ return this._hashFn;
424
+ }
425
+
426
+ protected _objHashFn: (key: K) => object = (key: K) => <object>key;
427
+
428
+ /**
429
+ * The function returns the object hash function.
430
+ * @returns The function `objHashFn` is being returned.
431
+ */
432
+ get objHashFn(): (key: K) => object {
433
+ return this._objHashFn;
434
+ }
435
+
436
+ protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};
437
+
438
+ /**
439
+ * The function returns a record of HashMapLinkedNode objects with string keys.
440
+ * @returns The method is returning a Record object, which is a TypeScript type that represents an
441
+ * object with string keys and values that are HashMapLinkedNode objects with keys of type K and
442
+ * values of type V or undefined.
443
+ */
444
+ get noObjMap(): Record<string, HashMapLinkedNode<K, V | undefined>> {
445
+ return this._noObjMap;
446
+ }
447
+
448
+ protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();
449
+
450
+ /**
451
+ * The function returns the WeakMap object used to map objects to HashMapLinkedNode instances.
452
+ * @returns The `objMap` property is being returned.
453
+ */
454
+ get objMap(): WeakMap<object, HashMapLinkedNode<K, V | undefined>> {
455
+ return this._objMap;
456
+ }
457
+
458
+ protected _head: HashMapLinkedNode<K, V | undefined>;
459
+
460
+ /**
461
+ * The function returns the head node of a HashMapLinkedNode.
462
+ * @returns The method `getHead()` is returning a `HashMapLinkedNode` object with key type `K` and
463
+ * value type `V | undefined`.
464
+ */
465
+ get head(): HashMapLinkedNode<K, V | undefined> {
466
+ return this._head;
467
+ }
468
+
469
+ protected _tail: HashMapLinkedNode<K, V | undefined>;
470
+
471
+ /**
472
+ * The function returns the tail node of a HashMapLinkedNode.
473
+ * @returns The `_tail` property of type `HashMapLinkedNode<K, V | undefined>` is being returned.
474
+ */
475
+ get tail(): HashMapLinkedNode<K, V | undefined> {
476
+ return this._tail;
477
+ }
478
+
479
+ protected _toEntryFn: (rawElement: R) => [K, V] = (rawElement: R) => {
480
+ if (this.isEntry(rawElement)) {
481
+ // TODO, For performance optimization, it may be necessary to only inspect the first element traversed.
482
+ return rawElement;
483
+ } else {
484
+ throw new Error(
485
+ "If the provided rawCollection does not adhere to the [key, value] type format, the toEntryFn in the constructor's options parameter needs to specified."
486
+ );
487
+ }
488
+ };
489
+
490
+ /**
491
+ * The function returns the value of the _toEntryFn property.
492
+ * @returns The function being returned is `this._toEntryFn`.
493
+ */
494
+ get toEntryFn() {
495
+ return this._toEntryFn;
496
+ }
497
+
316
498
  protected _size = 0;
317
499
 
500
+ /**
501
+ * The function returns the size of an object.
502
+ * @returns The size of the object.
503
+ */
318
504
  get size() {
319
505
  return this._size;
320
506
  }
321
507
 
508
+ /**
509
+ * Time Complexity: O(1)
510
+ * Space Complexity: O(1)
511
+ */
512
+
322
513
  /**
323
514
  * Time Complexity: O(1)
324
515
  * Space Complexity: O(1)
@@ -329,9 +520,14 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
329
520
  */
330
521
  get first() {
331
522
  if (this._size === 0) return;
332
- return <[K, V]>[this._head.key, this._head.value];
523
+ return <[K, V]>[this.head.key, this.head.value];
333
524
  }
334
525
 
526
+ /**
527
+ * Time Complexity: O(1)
528
+ * Space Complexity: O(1)
529
+ */
530
+
335
531
  /**
336
532
  * Time Complexity: O(1)
337
533
  * Space Complexity: O(1)
@@ -342,14 +538,14 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
342
538
  */
343
539
  get last() {
344
540
  if (this._size === 0) return;
345
- return <[K, V]>[this._tail.key, this._tail.value];
541
+ return <[K, V]>[this.tail.key, this.tail.value];
346
542
  }
347
543
 
348
544
  /**
349
545
  * The `begin()` function in TypeScript iterates over a linked list and yields key-value pairs.
350
546
  */
351
547
  * begin() {
352
- let node = this._head;
548
+ let node = this.head;
353
549
  while (node !== this._sentinel) {
354
550
  yield [node.key, node.value];
355
551
  node = node.next;
@@ -361,13 +557,18 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
361
557
  * key and value.
362
558
  */
363
559
  * reverseBegin() {
364
- let node = this._tail;
560
+ let node = this.tail;
365
561
  while (node !== this._sentinel) {
366
562
  yield [node.key, node.value];
367
563
  node = node.prev;
368
564
  }
369
565
  }
370
566
 
567
+ /**
568
+ * Time Complexity: O(1)
569
+ * Space Complexity: O(1)
570
+ */
571
+
371
572
  /**
372
573
  * Time Complexity: O(1)
373
574
  * Space Complexity: O(1)
@@ -385,23 +586,23 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
385
586
  const isNewKey = !this.has(key); // Check if the key is new
386
587
 
387
588
  if (isWeakKey(key)) {
388
- const hash = this._objHashFn(key);
389
- node = this._objMap.get(hash);
589
+ const hash = this.objHashFn(key);
590
+ node = this.objMap.get(hash);
390
591
 
391
592
  if (!node && isNewKey) {
392
593
  // Create new node
393
- node = { key: <K>hash, value, prev: this._tail, next: this._sentinel };
394
- this._objMap.set(hash, node);
594
+ node = { key: <K>hash, value, prev: this.tail, next: this._sentinel };
595
+ this.objMap.set(hash, node);
395
596
  } else if (node) {
396
597
  // Update the value of an existing node
397
598
  node.value = value;
398
599
  }
399
600
  } else {
400
- const hash = this._hashFn(key);
401
- node = this._noObjMap[hash];
601
+ const hash = this.hashFn(key);
602
+ node = this.noObjMap[hash];
402
603
 
403
604
  if (!node && isNewKey) {
404
- this._noObjMap[hash] = node = { key, value, prev: this._tail, next: this._sentinel };
605
+ this.noObjMap[hash] = node = { key, value, prev: this.tail, next: this._sentinel };
405
606
  } else if (node) {
406
607
  // Update the value of an existing node
407
608
  node.value = value;
@@ -414,8 +615,8 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
414
615
  this._head = node;
415
616
  this._sentinel.next = node;
416
617
  } else {
417
- this._tail.next = node;
418
- node.prev = this._tail; // Make sure that the prev of the new node points to the current tail node
618
+ this.tail.next = node;
619
+ node.prev = this.tail; // Make sure that the prev of the new node points to the current tail node
419
620
  }
420
621
  this._tail = node;
421
622
  this._sentinel.prev = node;
@@ -425,25 +626,44 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
425
626
  return true;
426
627
  }
427
628
 
428
- has(key: K): boolean {
429
- if (isWeakKey(key)) {
430
- const hash = this._objHashFn(key);
431
- return this._objMap.has(hash);
432
- } else {
433
- const hash = this._hashFn(key);
434
- return hash in this._noObjMap;
435
- }
436
- }
437
-
438
- setMany(entries: Iterable<[K, V]>): boolean[] {
629
+ /**
630
+ * The function `setMany` takes an iterable collection, converts each element into a key-value pair
631
+ * using a provided function, and sets each key-value pair in the current object, returning an array
632
+ * of booleans indicating the success of each set operation.
633
+ * @param rawCollection - The rawCollection parameter is an iterable collection of elements of type
634
+ * R.
635
+ * @returns The `setMany` function returns an array of booleans.
636
+ */
637
+ setMany(rawCollection: Iterable<R>): boolean[] {
439
638
  const results: boolean[] = [];
440
- for (const entry of entries) {
441
- const [key, value] = entry;
639
+ for (const rawEle of rawCollection) {
640
+ const [key, value] = this.toEntryFn(rawEle);
442
641
  results.push(this.set(key, value));
443
642
  }
444
643
  return results;
445
644
  }
446
645
 
646
+ /**
647
+ * The function checks if a given key exists in a map, using different logic depending on whether the
648
+ * key is a weak key or not.
649
+ * @param {K} key - The `key` parameter is the key that is being checked for existence in the map.
650
+ * @returns The method `has` is returning a boolean value.
651
+ */
652
+ override has(key: K): boolean {
653
+ if (isWeakKey(key)) {
654
+ const hash = this.objHashFn(key);
655
+ return this.objMap.has(hash);
656
+ } else {
657
+ const hash = this.hashFn(key);
658
+ return hash in this.noObjMap;
659
+ }
660
+ }
661
+
662
+ /**
663
+ * Time Complexity: O(1)
664
+ * Space Complexity: O(1)
665
+ */
666
+
447
667
  /**
448
668
  * Time Complexity: O(1)
449
669
  * Space Complexity: O(1)
@@ -457,32 +677,37 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
457
677
  * property of the key. If the key is a string key, the value is retrieved from the `_noObjMap` object
458
678
  * using the key itself. If the key is not found, `undefined` is
459
679
  */
460
- get(key: K): V | undefined {
680
+ override get(key: K): V | undefined {
461
681
  if (isWeakKey(key)) {
462
- const hash = this._objHashFn(key);
463
- const node = this._objMap.get(hash);
682
+ const hash = this.objHashFn(key);
683
+ const node = this.objMap.get(hash);
464
684
  return node ? node.value : undefined;
465
685
  } else {
466
- const hash = this._hashFn(key);
467
- const node = this._noObjMap[hash];
686
+ const hash = this.hashFn(key);
687
+ const node = this.noObjMap[hash];
468
688
  return node ? node.value : undefined;
469
689
  }
470
690
  }
471
691
 
472
692
  /**
473
- * Time Complexity: O(n), where n is the index.
693
+ * Time Complexity: O(n)
694
+ * Space Complexity: O(1)
695
+ * /
696
+
697
+ /**
698
+ * Time Complexity: O(n)
474
699
  * Space Complexity: O(1)
475
700
  *
476
- * The function `getAt` retrieves the key-value pair at a specified index in a linked list.
701
+ * The function `at` retrieves the key-value pair at a specified index in a linked list.
477
702
  * @param {number} index - The index parameter is a number that represents the position of the
478
703
  * element we want to retrieve from the data structure.
479
- * @returns The method `getAt(index: number)` is returning an array containing the key-value pair at
704
+ * @returns The method `at(index: number)` is returning an array containing the key-value pair at
480
705
  * the specified index in the data structure. The key-value pair is represented as a tuple `[K, V]`,
481
706
  * where `K` is the key and `V` is the value.
482
707
  */
483
- getAt(index: number): V | undefined {
708
+ at(index: number): V | undefined {
484
709
  rangeCheck(index, 0, this._size - 1);
485
- let node = this._head;
710
+ let node = this.head;
486
711
  while (index--) {
487
712
  node = node.next;
488
713
  }
@@ -490,6 +715,11 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
490
715
  }
491
716
 
492
717
  /**
718
+ * Time Complexity: O(1)
719
+ * Space Complexity: O(1)
720
+ * /
721
+
722
+ /**
493
723
  * Time Complexity: O(1)
494
724
  * Space Complexity: O(1)
495
725
  *
@@ -503,27 +733,27 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
503
733
  let node;
504
734
 
505
735
  if (isWeakKey(key)) {
506
- const hash = this._objHashFn(key);
736
+ const hash = this.objHashFn(key);
507
737
  // Get nodes from WeakMap
508
- node = this._objMap.get(hash);
738
+ node = this.objMap.get(hash);
509
739
 
510
740
  if (!node) {
511
741
  return false; // If the node does not exist, return false
512
742
  }
513
743
 
514
744
  // Remove nodes from WeakMap
515
- this._objMap.delete(hash);
745
+ this.objMap.delete(hash);
516
746
  } else {
517
- const hash = this._hashFn(key);
747
+ const hash = this.hashFn(key);
518
748
  // Get nodes from noObjMap
519
- node = this._noObjMap[hash];
749
+ node = this.noObjMap[hash];
520
750
 
521
751
  if (!node) {
522
752
  return false; // If the node does not exist, return false
523
753
  }
524
754
 
525
755
  // Remove nodes from orgMap
526
- delete this._noObjMap[hash];
756
+ delete this.noObjMap[hash];
527
757
  }
528
758
 
529
759
  // Remove node from doubly linked list
@@ -532,7 +762,12 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
532
762
  }
533
763
 
534
764
  /**
535
- * Time Complexity: O(n), where n is the index.
765
+ * Time Complexity: O(n)
766
+ * Space Complexity: O(1)
767
+ * /
768
+
769
+ /**
770
+ * Time Complexity: O(n)
536
771
  * Space Complexity: O(1)
537
772
  *
538
773
  * The `deleteAt` function deletes a node at a specified index in a linked list.
@@ -542,7 +777,7 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
542
777
  */
543
778
  deleteAt(index: number): boolean {
544
779
  rangeCheck(index, 0, this._size - 1);
545
- let node = this._head;
780
+ let node = this.head;
546
781
  while (index--) {
547
782
  node = node.next;
548
783
  }
@@ -550,6 +785,11 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
550
785
  }
551
786
 
552
787
  /**
788
+ * Time Complexity: O(1)
789
+ * Space Complexity: O(1)
790
+ * /
791
+
792
+ /**
553
793
  * Time Complexity: O(1)
554
794
  * Space Complexity: O(1)
555
795
  *
@@ -562,6 +802,21 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
562
802
  }
563
803
 
564
804
  /**
805
+ * The function checks if a given element is an array with exactly two elements.
806
+ * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any
807
+ * data type.
808
+ * @returns a boolean value.
809
+ */
810
+ isEntry(rawElement: any): rawElement is [K, V] {
811
+ return Array.isArray(rawElement) && rawElement.length === 2;
812
+ }
813
+
814
+ /**
815
+ * Time Complexity: O(1)
816
+ * Space Complexity: O(1)
817
+ * /
818
+
819
+ /**
565
820
  * Time Complexity: O(1)
566
821
  * Space Complexity: O(1)
567
822
  *
@@ -573,8 +828,22 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
573
828
  this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;
574
829
  }
575
830
 
831
+ /**
832
+ * Time Complexity: O(n)
833
+ * Space Complexity: O(n)
834
+ */
835
+
836
+ /**
837
+ * Time Complexity: O(n)
838
+ * Space Complexity: O(n)
839
+ *
840
+ * The `clone` function creates a new instance of a `LinkedHashMap` with the same key-value pairs as
841
+ * the original.
842
+ * @returns The `clone()` method is returning a new instance of `LinkedHashMap<K, V>` that is a clone
843
+ * of the original `LinkedHashMap` object.
844
+ */
576
845
  clone(): LinkedHashMap<K, V> {
577
- const cloned = new LinkedHashMap<K, V>([], { hashFn: this._hashFn, objHashFn: this._objHashFn });
846
+ const cloned = new LinkedHashMap<K, V>([], { hashFn: this.hashFn, objHashFn: this.objHashFn });
578
847
  for (const entry of this) {
579
848
  const [key, value] = entry;
580
849
  cloned.set(key, value);
@@ -583,6 +852,11 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
583
852
  }
584
853
 
585
854
  /**
855
+ * Time Complexity: O(n)
856
+ * Space Complexity: O(n)
857
+ * /
858
+
859
+ /**
586
860
  * Time Complexity: O(n)
587
861
  * Space Complexity: O(n)
588
862
  *
@@ -610,6 +884,11 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
610
884
  }
611
885
 
612
886
  /**
887
+ * Time Complexity: O(n)
888
+ * Space Complexity: O(n)
889
+ * /
890
+
891
+ /**
613
892
  * Time Complexity: O(n)
614
893
  * Space Complexity: O(n)
615
894
  *
@@ -638,37 +917,51 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
638
917
  }
639
918
 
640
919
  /**
641
- * Time Complexity: O(n)
642
- * Space Complexity: O(n)
920
+ * Time Complexity: O(1)
921
+ * Space Complexity: O(1)
643
922
  */
644
923
 
924
+ /**
925
+ * Time Complexity: O(1)
926
+ * Space Complexity: O(1)
927
+ *
928
+ * The put function sets a value in a data structure using a specified key.
929
+ * @param {K} key - The key parameter is of type K, which represents the type of the key being passed
930
+ * to the function.
931
+ * @param {V} value - The value parameter represents the value that you want to associate with the
932
+ * specified key in the data structure.
933
+ * @returns The method is returning a boolean value.
934
+ */
645
935
  put(key: K, value: V): boolean {
646
936
  return this.set(key, value);
647
937
  }
648
938
 
649
939
  /**
650
940
  * Time Complexity: O(n)
651
- * Space Complexity: O(n)
652
- */
653
-
654
- protected _hashFn: (key: K) => string = (key: K) => String(key);
655
-
656
- protected _objHashFn: (key: K) => object = (key: K) => <object>key;
941
+ * Space Complexity: O(1)
942
+ * where n is the number of entries in the LinkedHashMap.
943
+ * /
657
944
 
658
- /**
659
- * Time Complexity: O(n), where n is the number of entries in the LinkedHashMap.
945
+ /**
946
+ * Time Complexity: O(n)
660
947
  * Space Complexity: O(1)
948
+ * where n is the number of entries in the LinkedHashMap.
661
949
  *
662
950
  * The above function is an iterator that yields key-value pairs from a linked list.
663
951
  */
664
952
  protected* _getIterator() {
665
- let node = this._head;
953
+ let node = this.head;
666
954
  while (node !== this._sentinel) {
667
955
  yield [node.key, node.value] as [K, V];
668
956
  node = node.next;
669
957
  }
670
958
  }
671
959
 
960
+ /**
961
+ * Time Complexity: O(1)
962
+ * Space Complexity: O(1)
963
+ */
964
+
672
965
  /**
673
966
  * Time Complexity: O(1)
674
967
  * Space Complexity: O(1)
@@ -684,11 +977,11 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
684
977
  prev.next = next;
685
978
  next.prev = prev;
686
979
 
687
- if (node === this._head) {
980
+ if (node === this.head) {
688
981
  this._head = next;
689
982
  }
690
983
 
691
- if (node === this._tail) {
984
+ if (node === this.tail) {
692
985
  this._tail = prev;
693
986
  }
694
987