bst-typed 2.0.5 → 2.1.1

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 (101) hide show
  1. package/dist/data-structures/base/iterable-element-base.d.ts +186 -83
  2. package/dist/data-structures/base/iterable-element-base.js +149 -107
  3. package/dist/data-structures/base/iterable-entry-base.d.ts +95 -119
  4. package/dist/data-structures/base/iterable-entry-base.js +59 -116
  5. package/dist/data-structures/base/linear-base.d.ts +250 -192
  6. package/dist/data-structures/base/linear-base.js +137 -274
  7. package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
  8. package/dist/data-structures/binary-tree/avl-tree-counter.js +171 -205
  9. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
  10. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +135 -87
  11. package/dist/data-structures/binary-tree/avl-tree.d.ts +138 -149
  12. package/dist/data-structures/binary-tree/avl-tree.js +208 -195
  13. package/dist/data-structures/binary-tree/binary-tree.d.ts +476 -632
  14. package/dist/data-structures/binary-tree/binary-tree.js +602 -873
  15. package/dist/data-structures/binary-tree/bst.d.ts +258 -306
  16. package/dist/data-structures/binary-tree/bst.js +505 -481
  17. package/dist/data-structures/binary-tree/red-black-tree.d.ts +107 -179
  18. package/dist/data-structures/binary-tree/red-black-tree.js +114 -209
  19. package/dist/data-structures/binary-tree/tree-counter.d.ts +132 -154
  20. package/dist/data-structures/binary-tree/tree-counter.js +172 -203
  21. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
  22. package/dist/data-structures/binary-tree/tree-multi-map.js +105 -85
  23. package/dist/data-structures/graph/abstract-graph.d.ts +238 -233
  24. package/dist/data-structures/graph/abstract-graph.js +267 -237
  25. package/dist/data-structures/graph/directed-graph.d.ts +108 -224
  26. package/dist/data-structures/graph/directed-graph.js +146 -233
  27. package/dist/data-structures/graph/map-graph.d.ts +49 -55
  28. package/dist/data-structures/graph/map-graph.js +56 -59
  29. package/dist/data-structures/graph/undirected-graph.d.ts +103 -146
  30. package/dist/data-structures/graph/undirected-graph.js +129 -149
  31. package/dist/data-structures/hash/hash-map.d.ts +164 -338
  32. package/dist/data-structures/hash/hash-map.js +270 -457
  33. package/dist/data-structures/heap/heap.d.ts +214 -289
  34. package/dist/data-structures/heap/heap.js +340 -349
  35. package/dist/data-structures/heap/max-heap.d.ts +11 -47
  36. package/dist/data-structures/heap/max-heap.js +11 -66
  37. package/dist/data-structures/heap/min-heap.d.ts +12 -47
  38. package/dist/data-structures/heap/min-heap.js +11 -66
  39. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
  40. package/dist/data-structures/linked-list/doubly-linked-list.js +368 -494
  41. package/dist/data-structures/linked-list/singly-linked-list.d.ts +261 -310
  42. package/dist/data-structures/linked-list/singly-linked-list.js +447 -466
  43. package/dist/data-structures/linked-list/skip-linked-list.d.ts +0 -107
  44. package/dist/data-structures/linked-list/skip-linked-list.js +0 -100
  45. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
  46. package/dist/data-structures/priority-queue/max-priority-queue.js +11 -78
  47. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
  48. package/dist/data-structures/priority-queue/min-priority-queue.js +10 -79
  49. package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -61
  50. package/dist/data-structures/priority-queue/priority-queue.js +8 -83
  51. package/dist/data-structures/queue/deque.d.ts +227 -254
  52. package/dist/data-structures/queue/deque.js +309 -348
  53. package/dist/data-structures/queue/queue.d.ts +180 -201
  54. package/dist/data-structures/queue/queue.js +265 -248
  55. package/dist/data-structures/stack/stack.d.ts +124 -102
  56. package/dist/data-structures/stack/stack.js +181 -125
  57. package/dist/data-structures/trie/trie.d.ts +164 -165
  58. package/dist/data-structures/trie/trie.js +189 -172
  59. package/dist/interfaces/binary-tree.d.ts +56 -6
  60. package/dist/interfaces/graph.d.ts +16 -0
  61. package/dist/types/data-structures/base/base.d.ts +1 -1
  62. package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -0
  63. package/dist/types/utils/utils.d.ts +1 -0
  64. package/dist/utils/utils.d.ts +1 -1
  65. package/dist/utils/utils.js +2 -1
  66. package/package.json +2 -2
  67. package/src/data-structures/base/iterable-element-base.ts +238 -115
  68. package/src/data-structures/base/iterable-entry-base.ts +96 -120
  69. package/src/data-structures/base/linear-base.ts +271 -277
  70. package/src/data-structures/binary-tree/avl-tree-counter.ts +196 -217
  71. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +188 -102
  72. package/src/data-structures/binary-tree/avl-tree.ts +237 -206
  73. package/src/data-structures/binary-tree/binary-tree.ts +665 -896
  74. package/src/data-structures/binary-tree/bst.ts +565 -572
  75. package/src/data-structures/binary-tree/red-black-tree.ts +157 -223
  76. package/src/data-structures/binary-tree/tree-counter.ts +195 -219
  77. package/src/data-structures/binary-tree/tree-multi-map.ts +127 -98
  78. package/src/data-structures/graph/abstract-graph.ts +339 -264
  79. package/src/data-structures/graph/directed-graph.ts +146 -236
  80. package/src/data-structures/graph/map-graph.ts +63 -60
  81. package/src/data-structures/graph/undirected-graph.ts +129 -152
  82. package/src/data-structures/hash/hash-map.ts +274 -496
  83. package/src/data-structures/heap/heap.ts +389 -402
  84. package/src/data-structures/heap/max-heap.ts +12 -76
  85. package/src/data-structures/heap/min-heap.ts +13 -76
  86. package/src/data-structures/linked-list/doubly-linked-list.ts +426 -530
  87. package/src/data-structures/linked-list/singly-linked-list.ts +495 -517
  88. package/src/data-structures/linked-list/skip-linked-list.ts +1 -108
  89. package/src/data-structures/priority-queue/max-priority-queue.ts +12 -87
  90. package/src/data-structures/priority-queue/min-priority-queue.ts +11 -88
  91. package/src/data-structures/priority-queue/priority-queue.ts +3 -92
  92. package/src/data-structures/queue/deque.ts +381 -357
  93. package/src/data-structures/queue/queue.ts +310 -264
  94. package/src/data-structures/stack/stack.ts +217 -131
  95. package/src/data-structures/trie/trie.ts +240 -175
  96. package/src/interfaces/binary-tree.ts +240 -6
  97. package/src/interfaces/graph.ts +37 -0
  98. package/src/types/data-structures/base/base.ts +5 -5
  99. package/src/types/data-structures/graph/abstract-graph.ts +5 -0
  100. package/src/types/utils/utils.ts +2 -0
  101. package/src/utils/utils.ts +9 -14
@@ -1,9 +1,21 @@
1
1
  "use strict";
2
+ /**
3
+ * data-structure-typed
4
+ *
5
+ * @author Pablo Zeng
6
+ * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
7
+ * @license MIT License
8
+ */
2
9
  Object.defineProperty(exports, "__esModule", { value: true });
3
10
  exports.LinkedHashMap = exports.HashMap = void 0;
4
11
  const base_1 = require("../base");
5
12
  const utils_1 = require("../../utils");
6
13
  /**
14
+ * Hash-based map. Supports object keys and custom hashing; offers O(1) average set/get/has.
15
+ * @remarks Time O(1), Space O(1)
16
+ * @template K
17
+ * @template V
18
+ * @template R
7
19
  * 1. Key-Value Pair Storage: HashMap stores key-value pairs. Each key map to a value.
8
20
  * 2. Fast Lookup: It's used when you need to quickly find, insert, or delete entries based on a key.
9
21
  * 3. Unique Keys: Keys are unique.
@@ -58,11 +70,11 @@ const utils_1 = require("../../utils");
58
70
  */
59
71
  class HashMap extends base_1.IterableEntryBase {
60
72
  /**
61
- * The constructor function initializes a HashMap object with an optional initial collection and
62
- * options.
63
- * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type
64
- * `T`. It is an optional parameter and its default value is an empty array `[]`.
65
- * @param [options] - The `options` parameter is an optional object that can contain two properties:
73
+ * Create a HashMap and optionally bulk-insert entries.
74
+ * @remarks Time O(N), Space O(N)
75
+ * @param [entryOrRawElements] - Iterable of entries or raw elements to insert.
76
+ * @param [options] - Options: hash function and optional record-to-entry converter.
77
+ * @returns New HashMap instance.
66
78
  */
67
79
  constructor(entryOrRawElements = [], options) {
68
80
  super();
@@ -77,77 +89,61 @@ class HashMap extends base_1.IterableEntryBase {
77
89
  if (toEntryFn)
78
90
  this._toEntryFn = toEntryFn;
79
91
  }
80
- if (entryOrRawElements) {
92
+ if (entryOrRawElements)
81
93
  this.setMany(entryOrRawElements);
82
- }
83
94
  }
84
95
  /**
85
- * The function returns the store object, which is a dictionary of HashMapStoreItem objects.
86
- * @returns The store property is being returned. It is a dictionary-like object with string keys and
87
- * values of type HashMapStoreItem<K, V>.
96
+ * Get the internal store for non-object keys.
97
+ * @remarks Time O(1), Space O(1)
98
+ * @returns Internal record of string→{key,value}.
88
99
  */
89
100
  get store() {
90
101
  return this._store;
91
102
  }
92
103
  /**
93
- * The function returns the object map.
94
- * @returns The `objMap` property is being returned, which is a `Map` object with keys of type
95
- * `object` and values of type `V`.
104
+ * Get the internal Map used for object/function keys.
105
+ * @remarks Time O(1), Space O(1)
106
+ * @returns Map of object→value.
96
107
  */
97
108
  get objMap() {
98
109
  return this._objMap;
99
110
  }
100
111
  /**
101
- * The function returns the value of the _toEntryFn property.
102
- * @returns The function being returned is `this._toEntryFn`.
112
+ * Get the raw→entry converter function if present.
113
+ * @remarks Time O(1), Space O(1)
114
+ * @returns Converter function or undefined.
103
115
  */
104
116
  get toEntryFn() {
105
117
  return this._toEntryFn;
106
118
  }
107
119
  /**
108
- * The function returns the size of an object.
109
- * @returns The size of the object, which is a number.
120
+ * Get the number of distinct keys stored.
121
+ * @remarks Time O(1), Space O(1)
122
+ * @returns Current size.
110
123
  */
111
124
  get size() {
112
125
  return this._size;
113
126
  }
114
127
  /**
115
- * The hasFn function is a function that takes in an item and returns a boolean
116
- * indicating whether the item is contained within the hash table.
117
- *
118
- * @return The hash function
128
+ * Get the current hash function for non-object keys.
129
+ * @remarks Time O(1), Space O(1)
130
+ * @returns Hash function.
119
131
  */
120
132
  get hashFn() {
121
133
  return this._hashFn;
122
134
  }
123
135
  /**
124
- * Time Complexity: O(1)
125
- * Space Complexity: O(1)
126
- *
127
- * The function checks if a given element is an array with exactly two elements.
128
- * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any
129
- * data type.
130
- * @returns a boolean value.
131
- */
132
- isEntry(rawElement) {
133
- return Array.isArray(rawElement) && rawElement.length === 2;
134
- }
135
- /**
136
- * Time Complexity: O(1)
137
- * Space Complexity: O(1)
138
- *
139
- * The function checks if the size of an object is equal to zero and returns a boolean value.
140
- * @returns A boolean value indicating whether the size of the object is 0 or not.
136
+ * Check whether the map is empty.
137
+ * @remarks Time O(1), Space O(1)
138
+ * @returns True if size is 0.
141
139
  */
142
140
  isEmpty() {
143
141
  return this._size === 0;
144
142
  }
145
143
  /**
146
- * Time Complexity: O(1)
147
- * Space Complexity: O(1)
148
- *
149
- * The clear() function resets the state of an object by clearing its internal store, object map, and
150
- * size.
144
+ * Remove all entries and reset counters.
145
+ * @remarks Time O(N), Space O(1)
146
+ * @returns void
151
147
  */
152
148
  clear() {
153
149
  this._store = {};
@@ -155,216 +151,182 @@ class HashMap extends base_1.IterableEntryBase {
155
151
  this._size = 0;
156
152
  }
157
153
  /**
158
- * Time Complexity: O(1)
159
- * Space Complexity: O(1)
160
- *
161
- * The `set` function adds a key-value pair to a map-like data structure, incrementing the size if
162
- * the key is not already present.
163
- * @param {K} key - The key parameter is the key used to identify the value in the data structure. It
164
- * can be of any type, but if it is an object, it will be stored in a Map, otherwise it will be
165
- * stored in a regular JavaScript object.
166
- * @param {V} value - The value parameter represents the value that you want to associate with the
167
- * key in the data structure.
154
+ * Type guard: check if a raw value is a [key, value] entry.
155
+ * @remarks Time O(1), Space O(1)
156
+ * @returns True if the value is a 2-tuple.
157
+ */
158
+ isEntry(rawElement) {
159
+ return Array.isArray(rawElement) && rawElement.length === 2;
160
+ }
161
+ /**
162
+ * Insert or replace a single entry.
163
+ * @remarks Time O(1), Space O(1)
164
+ * @param key - Key.
165
+ * @param value - Value.
166
+ * @returns True when the operation succeeds.
168
167
  */
169
168
  set(key, value) {
170
169
  if (this._isObjKey(key)) {
171
- if (!this.objMap.has(key)) {
170
+ if (!this.objMap.has(key))
172
171
  this._size++;
173
- }
174
172
  this.objMap.set(key, value);
175
173
  }
176
174
  else {
177
175
  const strKey = this._getNoObjKey(key);
178
- if (this.store[strKey] === undefined) {
176
+ if (this.store[strKey] === undefined)
179
177
  this._size++;
180
- }
181
178
  this._store[strKey] = { key, value };
182
179
  }
183
180
  return true;
184
181
  }
185
182
  /**
186
- * Time Complexity: O(k)
187
- * Space Complexity: O(k)
188
- *
189
- * The function `setMany` takes an iterable collection of objects, maps each object to a key-value
190
- * pair using a mapping function, and sets each key-value pair in the current object.
191
- * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type
192
- * `T`.
193
- * @returns The `setMany` function is returning an array of booleans.
183
+ * Insert many entries from an iterable.
184
+ * @remarks Time O(N), Space O(N)
185
+ * @param entryOrRawElements - Iterable of entries or raw elements to insert.
186
+ * @returns Array of per-entry results.
194
187
  */
195
188
  setMany(entryOrRawElements) {
196
189
  const results = [];
197
190
  for (const rawEle of entryOrRawElements) {
198
191
  let key, value;
199
- if (this.isEntry(rawEle)) {
200
- key = rawEle[0];
201
- value = rawEle[1];
202
- }
203
- else if (this._toEntryFn) {
204
- const item = this._toEntryFn(rawEle);
205
- key = item[0];
206
- value = item[1];
207
- }
192
+ if (this.isEntry(rawEle))
193
+ [key, value] = rawEle;
194
+ else if (this._toEntryFn)
195
+ [key, value] = this._toEntryFn(rawEle);
208
196
  if (key !== undefined && value !== undefined)
209
197
  results.push(this.set(key, value));
210
198
  }
211
199
  return results;
212
200
  }
213
201
  /**
214
- * Time Complexity: O(1)
215
- * Space Complexity: O(1)
216
- *
217
- * The `get` function retrieves a value from a map based on a given key, either from an object map or
218
- * a string map.
219
- * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be
220
- * of any type, but it should be compatible with the key type used when the map was created.
221
- * @returns The method `get(key: K)` returns a value of type `V` if the key exists in the `_objMap`
222
- * or `_store`, otherwise it returns `undefined`.
202
+ * Get the value for a key.
203
+ * @remarks Time O(1), Space O(1)
204
+ * @param key - Key to look up.
205
+ * @returns Value or undefined.
223
206
  */
224
207
  get(key) {
225
208
  var _a;
226
- if (this._isObjKey(key)) {
209
+ if (this._isObjKey(key))
227
210
  return this.objMap.get(key);
228
- }
229
- else {
230
- const strKey = this._getNoObjKey(key);
231
- return (_a = this._store[strKey]) === null || _a === void 0 ? void 0 : _a.value;
232
- }
211
+ const strKey = this._getNoObjKey(key);
212
+ return (_a = this._store[strKey]) === null || _a === void 0 ? void 0 : _a.value;
233
213
  }
234
214
  /**
235
- * Time Complexity: O(1)
236
- * Space Complexity: O(1)
237
- *
238
- * The `has` function checks if a given key exists in the `_objMap` or `_store` based on whether it
239
- * is an object key or not.
240
- * @param {K} key - The parameter "key" is of type K, which means it can be any type.
241
- * @returns The `has` method is returning a boolean value.
215
+ * Check if a key exists.
216
+ * @remarks Time O(1), Space O(1)
217
+ * @param key - Key to test.
218
+ * @returns True if present.
242
219
  */
243
220
  has(key) {
244
- if (this._isObjKey(key)) {
221
+ if (this._isObjKey(key))
245
222
  return this.objMap.has(key);
246
- }
247
- else {
248
- const strKey = this._getNoObjKey(key);
249
- return strKey in this.store;
250
- }
223
+ const strKey = this._getNoObjKey(key);
224
+ return strKey in this.store;
251
225
  }
252
226
  /**
253
- * Time Complexity: O(1)
254
- * Space Complexity: O(1)
255
- *
256
- * The `delete` function removes an element from a map-like data structure based on the provided key.
257
- * @param {K} key - The `key` parameter is the key of the element that you want to delete from the
258
- * data structure.
259
- * @returns The `delete` method returns a boolean value. It returns `true` if the key was
260
- * successfully deleted from the map, and `false` if the key was not found in the map.
227
+ * Delete an entry by key.
228
+ * @remarks Time O(1), Space O(1)
229
+ * @param key - Key to delete.
230
+ * @returns True if the key was found and removed.
261
231
  */
262
232
  delete(key) {
263
233
  if (this._isObjKey(key)) {
264
- if (this.objMap.has(key)) {
234
+ if (this.objMap.has(key))
265
235
  this._size--;
266
- }
267
236
  return this.objMap.delete(key);
268
237
  }
269
- else {
270
- const strKey = this._getNoObjKey(key);
271
- if (strKey in this.store) {
272
- delete this.store[strKey];
273
- this._size--;
274
- return true;
275
- }
276
- return false;
238
+ const strKey = this._getNoObjKey(key);
239
+ if (strKey in this.store) {
240
+ delete this.store[strKey];
241
+ this._size--;
242
+ return true;
277
243
  }
244
+ return false;
245
+ }
246
+ /**
247
+ * Replace the hash function and rehash the non-object store.
248
+ * @remarks Time O(N), Space O(N)
249
+ * @param fn - New hash function for non-object keys.
250
+ * @returns This map instance.
251
+ */
252
+ setHashFn(fn) {
253
+ if (this._hashFn === fn)
254
+ return this;
255
+ this._hashFn = fn;
256
+ this._rehashNoObj();
257
+ return this;
278
258
  }
279
259
  /**
280
- * Time Complexity: O(n)
281
- * Space Complexity: O(n)
282
- *
283
- * The clone function creates a new HashMap with the same key-value pairs as
284
- * this one. The clone function is useful for creating a copy of an existing
285
- * HashMap, and then modifying that copy without affecting the original.
286
- *
287
- * @return A new hashmap with the same values as this one
260
+ * Deep clone this map, preserving hashing behavior.
261
+ * @remarks Time O(N), Space O(N)
262
+ * @returns A new map with the same content.
288
263
  */
289
264
  clone() {
290
- return new HashMap(this, { hashFn: this._hashFn, toEntryFn: this._toEntryFn });
291
- }
292
- /**
293
- * Time Complexity: O(n)
294
- * Space Complexity: O(n)
295
- *
296
- * The `map` function in TypeScript creates a new HashMap by applying a callback function to each
297
- * key-value pair in the original HashMap.
298
- * @param callbackfn - The callback function that will be called for each key-value pair in the
299
- * HashMap. It takes four parameters:
300
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
301
- * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will
302
- * be passed as the `this` value to the `callbackfn` function. If `thisArg
303
- * @returns The `map` method is returning a new `HashMap` object with the transformed values based on
304
- * the provided callback function.
265
+ const opts = { hashFn: this._hashFn, toEntryFn: this._toEntryFn };
266
+ return this._createLike(this, opts);
267
+ }
268
+ /**
269
+ * Map values to a new map with the same keys.
270
+ * @remarks Time O(N), Space O(N)
271
+ * @template VM
272
+ * @param callbackfn - Mapping function (key, value, index, map) newValue.
273
+ * @param [thisArg] - Value for `this` inside the callback.
274
+ * @returns A new map with transformed values.
305
275
  */
306
276
  map(callbackfn, thisArg) {
307
- const resultMap = new HashMap();
277
+ const out = this._createLike();
308
278
  let index = 0;
309
- for (const [key, value] of this) {
310
- resultMap.set(key, callbackfn.call(thisArg, key, value, index++, this));
311
- }
312
- return resultMap;
313
- }
314
- /**
315
- * Time Complexity: O(n)
316
- * Space Complexity: O(n)
317
- *
318
- * The `filter` function creates a new HashMap containing key-value pairs from the original HashMap
319
- * that satisfy a given predicate function.
320
- * @param predicate - The predicate parameter is a function that takes four arguments: value, key,
321
- * index, and map. It is used to determine whether an element should be included in the filtered map
322
- * or not. The function should return a boolean value - true if the element should be included, and
323
- * false otherwise.
324
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
325
- * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be
326
- * passed as the `this` value to the `predicate` function. If `thisArg` is
327
- * @returns The `filter` method is returning a new `HashMap` object that contains the key-value pairs
328
- * from the original `HashMap` that pass the provided `predicate` function.
279
+ for (const [key, value] of this)
280
+ out.set(key, callbackfn.call(thisArg, key, value, index++, this));
281
+ return out;
282
+ }
283
+ /**
284
+ * Filter entries into a new map.
285
+ * @remarks Time O(N), Space O(N)
286
+ * @param predicate - Predicate (key, value, index, map) → boolean.
287
+ * @param [thisArg] - Value for `this` inside the predicate.
288
+ * @returns A new map containing entries that satisfied the predicate.
329
289
  */
330
290
  filter(predicate, thisArg) {
331
- const filteredMap = new HashMap();
291
+ const out = this._createLike();
332
292
  let index = 0;
333
- for (const [key, value] of this) {
334
- if (predicate.call(thisArg, key, value, index++, this)) {
335
- filteredMap.set(key, value);
336
- }
337
- }
338
- return filteredMap;
293
+ for (const [key, value] of this)
294
+ if (predicate.call(thisArg, key, value, index++, this))
295
+ out.set(key, value);
296
+ return out;
339
297
  }
340
298
  /**
341
- * The function returns an iterator that yields key-value pairs from both an object store and an
342
- * object map.
299
+ * (Protected) Create a like-kind instance and seed it from an iterable.
300
+ * @remarks Time O(N), Space O(N)
301
+ * @template TK
302
+ * @template TV
303
+ * @template TR
304
+ * @param [entries] - Iterable used to seed the new map.
305
+ * @param [options] - Options forwarded to the constructor.
306
+ * @returns A like-kind map instance.
343
307
  */
308
+ _createLike(entries = [], options) {
309
+ const Ctor = this.constructor;
310
+ return new Ctor(entries, options);
311
+ }
312
+ _rehashNoObj() {
313
+ const fresh = {};
314
+ for (const { key, value } of Object.values(this._store)) {
315
+ const sk = this._getNoObjKey(key);
316
+ fresh[sk] = { key, value };
317
+ }
318
+ this._store = fresh;
319
+ }
344
320
  *_getIterator() {
345
- for (const node of Object.values(this.store)) {
321
+ for (const node of Object.values(this.store))
346
322
  yield [node.key, node.value];
347
- }
348
- for (const node of this.objMap) {
323
+ for (const node of this.objMap)
349
324
  yield node;
350
- }
351
325
  }
352
- /**
353
- * The function checks if a given key is an object or a function.
354
- * @param {any} key - The parameter "key" can be of any type.
355
- * @returns a boolean value.
356
- */
357
326
  _isObjKey(key) {
358
327
  const keyType = typeof key;
359
328
  return (keyType === 'object' || keyType === 'function') && key !== null;
360
329
  }
361
- /**
362
- * The function `_getNoObjKey` takes a key and returns a string representation of the key, handling
363
- * different types of keys.
364
- * @param {K} key - The `key` parameter is of type `K`, which represents the type of the key being
365
- * passed to the `_getNoObjKey` function.
366
- * @returns a string value.
367
- */
368
330
  _getNoObjKey(key) {
369
331
  const keyType = typeof key;
370
332
  let strKey;
@@ -373,7 +335,6 @@ class HashMap extends base_1.IterableEntryBase {
373
335
  }
374
336
  else {
375
337
  if (keyType === 'number') {
376
- // TODO numeric key should has its own hash
377
338
  strKey = key;
378
339
  }
379
340
  else {
@@ -385,19 +346,20 @@ class HashMap extends base_1.IterableEntryBase {
385
346
  }
386
347
  exports.HashMap = HashMap;
387
348
  /**
388
- * 1. Maintaining the Order of Element Insertion: Unlike HashMap, LinkedHashMap maintains the order in which entries are inserted. Therefore, when you traverse it, entries will be returned in the order they were inserted into the map.
389
- * 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.
390
- * 3. Time Complexity: Similar to HashMap, LinkedHashMap offers constant-time performance for get and put operations in most cases.
349
+ * Hash-based map that preserves insertion order via a doubly-linked list.
350
+ * @remarks Time O(1), Space O(1)
351
+ * @template K
352
+ * @template V
353
+ * @template R
354
+ * @example examples will be generated by unit test
391
355
  */
392
356
  class LinkedHashMap extends base_1.IterableEntryBase {
393
357
  /**
394
- * The constructor initializes a LinkedHashMap object with an optional raw collection and options.
395
- * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements. It is
396
- * used to initialize the HashMapLinked instance with key-value pairs. Each element in the
397
- * `entryOrRawElements` is converted to a key-value pair using the `toEntryFn` function (if provided) and
398
- * then added to the HashMap
399
- * @param [options] - The `options` parameter is an optional object that can contain the following
400
- * properties:
358
+ * Create a LinkedHashMap and optionally bulk-insert entries.
359
+ * @remarks Time O(N), Space O(N)
360
+ * @param [entryOrRawElements] - Iterable of entries or raw elements to insert.
361
+ * @param [options] - Options: hash functions and optional record-to-entry converter.
362
+ * @returns New LinkedHashMap instance.
401
363
  */
402
364
  constructor(entryOrRawElements = [], options) {
403
365
  super();
@@ -407,12 +369,9 @@ class LinkedHashMap extends base_1.IterableEntryBase {
407
369
  this._objMap = new WeakMap();
408
370
  this._toEntryFn = (rawElement) => {
409
371
  if (this.isEntry(rawElement)) {
410
- // TODO, For performance optimization, it may be necessary to only inspect the first element traversed.
411
372
  return rawElement;
412
373
  }
413
- else {
414
- throw new Error("If the provided entryOrRawElements does not adhere to the [key, value] type format, the toEntryFn in the constructor's options parameter needs to specified.");
415
- }
374
+ throw new Error('If `entryOrRawElements` does not adhere to [key,value], provide `options.toEntryFn` to transform raw records.');
416
375
  };
417
376
  this._size = 0;
418
377
  this._sentinel = {};
@@ -423,80 +382,60 @@ class LinkedHashMap extends base_1.IterableEntryBase {
423
382
  this._hashFn = hashFn;
424
383
  if (objHashFn)
425
384
  this._objHashFn = objHashFn;
426
- if (toEntryFn) {
385
+ if (toEntryFn)
427
386
  this._toEntryFn = toEntryFn;
428
- }
429
387
  }
430
- if (entryOrRawElements) {
388
+ if (entryOrRawElements)
431
389
  this.setMany(entryOrRawElements);
432
- }
433
390
  }
434
- /**
435
- * The function returns the hash function used for generating a hash value for a given key.
436
- * @returns The hash function that takes a key of type K and returns a string.
437
- */
438
391
  get hashFn() {
439
392
  return this._hashFn;
440
393
  }
441
394
  /**
442
- * The function returns the object hash function.
443
- * @returns The function `objHashFn` is being returned.
395
+ * Get the hash function for object/weak keys.
396
+ * @remarks Time O(1), Space O(1)
397
+ * @returns Object-hash function.
444
398
  */
445
399
  get objHashFn() {
446
400
  return this._objHashFn;
447
401
  }
448
402
  /**
449
- * The function returns a record of HashMapLinkedNode objects with string keys.
450
- * @returns The method is returning a Record object, which is a TypeScript type that represents an
451
- * object with string keys and values that are HashMapLinkedNode objects with keys of type K and
452
- * values of type V or undefined.
403
+ * Get the internal record for non-object keys.
404
+ * @remarks Time O(1), Space O(1)
405
+ * @returns Record of hash→node.
453
406
  */
454
407
  get noObjMap() {
455
408
  return this._noObjMap;
456
409
  }
457
- /**
458
- * The function returns the WeakMap object used to map objects to HashMapLinkedNode instances.
459
- * @returns The `objMap` property is being returned.
460
- */
461
410
  get objMap() {
462
411
  return this._objMap;
463
412
  }
464
413
  /**
465
- * The function returns the head node of a HashMapLinkedNode.
466
- * @returns The method `getHead()` is returning a `HashMapLinkedNode` object with key type `K` and
467
- * a value type `V | undefined`.
414
+ * Get the head node (first entry) sentinel link.
415
+ * @remarks Time O(1), Space O(1)
416
+ * @returns Head node or sentinel.
468
417
  */
469
418
  get head() {
470
419
  return this._head;
471
420
  }
472
421
  /**
473
- * The function returns the tail node of a HashMapLinkedNode.
474
- * @returns The `_tail` property of type `HashMapLinkedNode<K, V | undefined>` is being returned.
422
+ * Get the tail node (last entry) sentinel link.
423
+ * @remarks Time O(1), Space O(1)
424
+ * @returns Tail node or sentinel.
475
425
  */
476
426
  get tail() {
477
427
  return this._tail;
478
428
  }
479
- /**
480
- * The function returns the value of the _toEntryFn property.
481
- * @returns The function being returned is `this._toEntryFn`.
482
- */
483
429
  get toEntryFn() {
484
430
  return this._toEntryFn;
485
431
  }
486
- /**
487
- * The function returns the size of an object.
488
- * @returns The size of the object.
489
- */
490
432
  get size() {
491
433
  return this._size;
492
434
  }
493
435
  /**
494
- * Time Complexity: O(1)
495
- * Space Complexity: O(1)
496
- *
497
- * The function returns the key-value pair at the front of a data structure.
498
- * @returns The front element of the data structure, represented as a tuple with a key (K) and a
499
- * value (V).
436
+ * Get the first [key, value] pair.
437
+ * @remarks Time O(1), Space O(1)
438
+ * @returns First entry or undefined when empty.
500
439
  */
501
440
  get first() {
502
441
  if (this._size === 0)
@@ -504,12 +443,9 @@ class LinkedHashMap extends base_1.IterableEntryBase {
504
443
  return [this.head.key, this.head.value];
505
444
  }
506
445
  /**
507
- * Time Complexity: O(1)
508
- * Space Complexity: O(1)
509
- *
510
- * The function returns the key-value pair at the end of a data structure.
511
- * @returns The method is returning an array containing the key-value pair of the tail element in the
512
- * data structure.
446
+ * Get the last [key, value] pair.
447
+ * @remarks Time O(1), Space O(1)
448
+ * @returns Last entry or undefined when empty.
513
449
  */
514
450
  get last() {
515
451
  if (this._size === 0)
@@ -517,7 +453,9 @@ class LinkedHashMap extends base_1.IterableEntryBase {
517
453
  return [this.tail.key, this.tail.value];
518
454
  }
519
455
  /**
520
- * The `begin()` function in TypeScript iterates over a linked list and yields key-value pairs.
456
+ * Iterate from head tail.
457
+ * @remarks Time O(N), Space O(1)
458
+ * @returns Iterator of [key, value].
521
459
  */
522
460
  *begin() {
523
461
  let node = this.head;
@@ -527,8 +465,9 @@ class LinkedHashMap extends base_1.IterableEntryBase {
527
465
  }
528
466
  }
529
467
  /**
530
- * The function `reverseBegin()` iterates over a linked list in reverse order, yielding each node's
531
- * key and value.
468
+ * Iterate from tail head.
469
+ * @remarks Time O(N), Space O(1)
470
+ * @returns Iterator of [key, value].
532
471
  */
533
472
  *reverseBegin() {
534
473
  let node = this.tail;
@@ -538,30 +477,23 @@ class LinkedHashMap extends base_1.IterableEntryBase {
538
477
  }
539
478
  }
540
479
  /**
541
- * Time Complexity: O(1)
542
- * Space Complexity: O(1)
543
- *
544
- * The `set` function adds a new key-value pair to a data structure, either using an object key or a
545
- * string key.
546
- * @param {K} key - The `key` parameter is the key to be set in the data structure. It can be of any
547
- * type, but typically it is a string or symbol.
548
- * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the
549
- * value associated with the key being set in the data structure.
550
- * @returns the size of the data structure after the key-value pair has been set.
480
+ * Insert or replace a single entry; preserves insertion order.
481
+ * @remarks Time O(1), Space O(1)
482
+ * @param key - Key.
483
+ * @param [value] - Value.
484
+ * @returns True when the operation succeeds.
551
485
  */
552
486
  set(key, value) {
553
487
  let node;
554
- const isNewKey = !this.has(key); // Check if the key is new
488
+ const isNewKey = !this.has(key);
555
489
  if ((0, utils_1.isWeakKey)(key)) {
556
490
  const hash = this._objHashFn(key);
557
491
  node = this.objMap.get(hash);
558
492
  if (!node && isNewKey) {
559
- // Create a new node
560
493
  node = { key: hash, value, prev: this.tail, next: this._sentinel };
561
494
  this.objMap.set(hash, node);
562
495
  }
563
496
  else if (node) {
564
- // Update the value of an existing node
565
497
  node.value = value;
566
498
  }
567
499
  }
@@ -572,19 +504,17 @@ class LinkedHashMap extends base_1.IterableEntryBase {
572
504
  this.noObjMap[hash] = node = { key, value, prev: this.tail, next: this._sentinel };
573
505
  }
574
506
  else if (node) {
575
- // Update the value of an existing node
576
507
  node.value = value;
577
508
  }
578
509
  }
579
510
  if (node && isNewKey) {
580
- // Update the head and tail of the linked list
581
511
  if (this._size === 0) {
582
512
  this._head = node;
583
513
  this._sentinel.next = node;
584
514
  }
585
515
  else {
586
516
  this.tail.next = node;
587
- node.prev = this.tail; // Make sure that the prev of the new node points to the current tail node
517
+ node.prev = this.tail;
588
518
  }
589
519
  this._tail = node;
590
520
  this._sentinel.prev = node;
@@ -592,259 +522,150 @@ class LinkedHashMap extends base_1.IterableEntryBase {
592
522
  }
593
523
  return true;
594
524
  }
595
- /**
596
- * Time Complexity: O(k)
597
- * Space Complexity: O(k)
598
- *
599
- * The function `setMany` takes an iterable collection, converts each element into a key-value pair
600
- * using a provided function, and sets each key-value pair in the current object, returning an array
601
- * of booleans indicating the success of each set operation.
602
- * @param entryOrRawElements - The entryOrRawElements parameter is an iterable collection of elements of type
603
- * R.
604
- * @returns The `setMany` function returns an array of booleans.
605
- */
606
525
  setMany(entryOrRawElements) {
607
526
  const results = [];
608
527
  for (const rawEle of entryOrRawElements) {
609
528
  let key, value;
610
- if (this.isEntry(rawEle)) {
611
- key = rawEle[0];
612
- value = rawEle[1];
613
- }
614
- else if (this._toEntryFn) {
615
- const item = this._toEntryFn(rawEle);
616
- key = item[0];
617
- value = item[1];
618
- }
529
+ if (this.isEntry(rawEle))
530
+ [key, value] = rawEle;
531
+ else if (this._toEntryFn)
532
+ [key, value] = this._toEntryFn(rawEle);
619
533
  if (key !== undefined && value !== undefined)
620
534
  results.push(this.set(key, value));
621
535
  }
622
536
  return results;
623
537
  }
624
- /**
625
- * Time Complexity: O(1)
626
- * Space Complexity: O(1)
627
- *
628
- * The function checks if a given key exists in a map, using different logic depending on whether the
629
- * key is a weak key or not.
630
- * @param {K} key - The `key` parameter is the key that is being checked for existence in the map.
631
- * @returns The method `has` is returning a boolean value.
632
- */
633
538
  has(key) {
634
539
  if ((0, utils_1.isWeakKey)(key)) {
635
540
  const hash = this._objHashFn(key);
636
541
  return this.objMap.has(hash);
637
542
  }
638
- else {
639
- const hash = this._hashFn(key);
640
- return hash in this.noObjMap;
641
- }
543
+ const hash = this._hashFn(key);
544
+ return hash in this.noObjMap;
642
545
  }
643
- /**
644
- * Time Complexity: O(1)
645
- * Space Complexity: O(1)
646
- *
647
- * The function `get` retrieves the value associated with a given key from a map, either by using the
648
- * key directly or by using an index stored in the key object.
649
- * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be
650
- * of any type, but typically it is a string or symbol.
651
- * @returns The value associated with the given key is being returned. If the key is an object key,
652
- * the value is retrieved from the `_nodes` array using the index stored in the `OBJ_KEY_INDEX`
653
- * property of the key. If the key is a string key, the value is retrieved from the `_noObjMap` object
654
- * using the key itself. If the key is not found, `undefined` is
655
- */
656
546
  get(key) {
657
547
  if ((0, utils_1.isWeakKey)(key)) {
658
548
  const hash = this._objHashFn(key);
659
549
  const node = this.objMap.get(hash);
660
550
  return node ? node.value : undefined;
661
551
  }
662
- else {
663
- const hash = this._hashFn(key);
664
- const node = this.noObjMap[hash];
665
- return node ? node.value : undefined;
666
- }
552
+ const hash = this._hashFn(key);
553
+ const node = this.noObjMap[hash];
554
+ return node ? node.value : undefined;
667
555
  }
668
556
  /**
669
- * Time Complexity: O(n)
670
- * Space Complexity: O(1)
671
- *
672
- * The function `at` retrieves the key-value pair at a specified index in a linked list.
673
- * @param {number} index - The index parameter is a number that represents the position of the
674
- * element we want to retrieve from the data structure.
675
- * @returns The method `at(index: number)` is returning an array containing the key-value pair at
676
- * the specified index in the data structure. The key-value pair is represented as a tuple `[K, V]`,
677
- * where `K` is the key and `V` is the value.
557
+ * Get the value at a given index in insertion order.
558
+ * @remarks Time O(N), Space O(1)
559
+ * @param index - Zero-based index.
560
+ * @returns Value at the index.
678
561
  */
679
562
  at(index) {
680
563
  (0, utils_1.rangeCheck)(index, 0, this._size - 1);
681
564
  let node = this.head;
682
- while (index--) {
565
+ while (index--)
683
566
  node = node.next;
684
- }
685
567
  return node.value;
686
568
  }
687
- /**
688
- * Time Complexity: O(1)
689
- * Space Complexity: O(1)
690
- *
691
- * The `delete` function removes a key-value pair from a map-like data structure.
692
- * @param {K} key - The `key` parameter is the key that you want to delete from the data structure.
693
- * It can be of any type, but typically it is a string or an object.
694
- * @returns a boolean value. It returns `true` if the deletion was successful, and `false` if the key
695
- * was not found.
696
- */
697
569
  delete(key) {
698
570
  let node;
699
571
  if ((0, utils_1.isWeakKey)(key)) {
700
572
  const hash = this._objHashFn(key);
701
- // Get nodes from WeakMap
702
573
  node = this.objMap.get(hash);
703
- if (!node) {
704
- return false; // If the node does not exist, return false
705
- }
706
- // Remove nodes from WeakMap
574
+ if (!node)
575
+ return false;
707
576
  this.objMap.delete(hash);
708
577
  }
709
578
  else {
710
579
  const hash = this._hashFn(key);
711
- // Get nodes from noObjMap
712
580
  node = this.noObjMap[hash];
713
- if (!node) {
714
- return false; // If the node does not exist, return false
715
- }
716
- // Remove nodes from orgMap
581
+ if (!node)
582
+ return false;
717
583
  delete this.noObjMap[hash];
718
584
  }
719
- // Remove node from doubly linked list
720
- this._deleteNode(node);
721
- return true;
585
+ return this._deleteNode(node);
722
586
  }
723
587
  /**
724
- * Time Complexity: O(n)
725
- * Space Complexity: O(1)
726
- *
727
- * The `deleteAt` function deletes a node at a specified index in a linked list.
728
- * @param {number} index - The index parameter represents the position at which the node should be
729
- * deleted in the linked list.
730
- * @returns The size of the list after deleting the element at the specified index.
588
+ * Delete the first entry that matches a predicate.
589
+ * @remarks Time O(N), Space O(1)
590
+ * @param predicate - Function (key, value, index, map) → boolean to decide deletion.
591
+ * @returns True if an entry was removed.
592
+ */
593
+ deleteWhere(predicate) {
594
+ let node = this._head;
595
+ let i = 0;
596
+ while (node !== this._sentinel) {
597
+ const cur = node;
598
+ node = node.next;
599
+ if (predicate(cur.key, cur.value, i++, this)) {
600
+ if ((0, utils_1.isWeakKey)(cur.key)) {
601
+ this._objMap.delete(cur.key);
602
+ }
603
+ else {
604
+ const hash = this._hashFn(cur.key);
605
+ delete this._noObjMap[hash];
606
+ }
607
+ return this._deleteNode(cur);
608
+ }
609
+ }
610
+ return false;
611
+ }
612
+ /**
613
+ * Delete the entry at a given index.
614
+ * @remarks Time O(N), Space O(1)
615
+ * @param index - Zero-based index.
616
+ * @returns True if removed.
731
617
  */
732
618
  deleteAt(index) {
733
619
  (0, utils_1.rangeCheck)(index, 0, this._size - 1);
734
620
  let node = this.head;
735
- while (index--) {
621
+ while (index--)
736
622
  node = node.next;
737
- }
738
623
  return this._deleteNode(node);
739
624
  }
740
- /**
741
- * Time Complexity: O(1)
742
- * Space Complexity: O(1)
743
- *
744
- * The function checks if a data structure is empty by comparing its size to zero.
745
- * @returns The method is returning a boolean value indicating whether the size of the object is 0 or
746
- * not.
747
- */
748
625
  isEmpty() {
749
626
  return this._size === 0;
750
627
  }
751
- /**
752
- * The function checks if a given element is an array with exactly two elements.
753
- * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any
754
- * data type.
755
- * @returns a boolean value.
756
- */
757
628
  isEntry(rawElement) {
758
629
  return Array.isArray(rawElement) && rawElement.length === 2;
759
630
  }
760
- /**
761
- * Time Complexity: O(1)
762
- * Space Complexity: O(1)
763
- *
764
- * The `clear` function clears all the entries in a data structure and resets its properties.
765
- */
766
631
  clear() {
767
632
  this._noObjMap = {};
768
633
  this._size = 0;
769
634
  this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;
770
635
  }
771
- /**
772
- * Time Complexity: O(n)
773
- * Space Complexity: O(n)
774
- *
775
- * The `clone` function creates a new instance of a `LinkedHashMap` with the same key-value pairs as
776
- * the original.
777
- * @returns The `clone()` method is returning a new instance of `LinkedHashMap<K, V>` that is a clone
778
- * of the original `LinkedHashMap` object.
779
- */
780
636
  clone() {
781
- const cloned = new LinkedHashMap([], { hashFn: this._hashFn, objHashFn: this._objHashFn });
782
- for (const entry of this) {
783
- const [key, value] = entry;
784
- cloned.set(key, value);
785
- }
786
- return cloned;
787
- }
788
- /**
789
- * Time Complexity: O(n)
790
- * Space Complexity: O(n)
791
- *
792
- * The `filter` function creates a new `LinkedHashMap` containing key-value pairs from the original
793
- * map that satisfy a given predicate function.
794
- * @param predicate - The `predicate` parameter is a callback function that takes four arguments:
795
- * `value`, `key`, `index`, and `this`. It should return a boolean value indicating whether the
796
- * current element should be included in the filtered map or not.
797
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
798
- * specify the value of `this` within the `predicate` function. It is used when you want to bind a
799
- * specific object as the context for the `predicate` function. If `thisArg` is not provided, `this
800
- * @returns a new `LinkedHashMap` object that contains the key-value pairs from the original
801
- * `LinkedHashMap` object that satisfy the given predicate function.
802
- */
637
+ const opts = { hashFn: this._hashFn, objHashFn: this._objHashFn };
638
+ return this._createLike(this, opts);
639
+ }
803
640
  filter(predicate, thisArg) {
804
- const filteredMap = new LinkedHashMap();
641
+ const out = this._createLike();
805
642
  let index = 0;
806
643
  for (const [key, value] of this) {
807
- if (predicate.call(thisArg, key, value, index, this)) {
808
- filteredMap.set(key, value);
809
- }
644
+ if (predicate.call(thisArg, key, value, index, this))
645
+ out.set(key, value);
810
646
  index++;
811
647
  }
812
- return filteredMap;
813
- }
814
- /**
815
- * Time Complexity: O(n)
816
- * Space Complexity: O(n)
817
- *
818
- * The `map` function in TypeScript creates a new `LinkedHashMap` by applying a callback function to
819
- * each key-value pair in the original map.
820
- * @param callback - The callback parameter is a function that will be called for each key-value pair
821
- * in the map. It takes four arguments: the value of the current key-value pair, the key of the
822
- * current key-value pair, the index of the current key-value pair, and the map itself. The callback
823
- * function should
824
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
825
- * specify the value of `this` within the callback function. If provided, the callback function will
826
- * be called with `thisArg` as its `this` value. If not provided, `this` will refer to the current
827
- * map
828
- * @returns a new `LinkedHashMap` object with the values mapped according to the provided callback
829
- * function.
648
+ return out;
649
+ }
650
+ /**
651
+ * Map each entry to a new [key, value] pair and preserve order.
652
+ * @remarks Time O(N), Space O(N)
653
+ * @template MK
654
+ * @template MV
655
+ * @param callback - Mapping function (key, value, index, map) [newKey, newValue].
656
+ * @param [thisArg] - Value for `this` inside the callback.
657
+ * @returns A new map of the same class with transformed entries.
830
658
  */
831
659
  map(callback, thisArg) {
832
- const mappedMap = new LinkedHashMap();
660
+ const out = this._createLike();
833
661
  let index = 0;
834
662
  for (const [key, value] of this) {
835
663
  const [newKey, newValue] = callback.call(thisArg, key, value, index, this);
836
- mappedMap.set(newKey, newValue);
664
+ out.set(newKey, newValue);
837
665
  index++;
838
666
  }
839
- return mappedMap;
667
+ return out;
840
668
  }
841
- /**
842
- * Time Complexity: O(n)
843
- * Space Complexity: O(1)
844
- * where n is the number of entries in the LinkedHashMap.
845
- *
846
- * The above function is an iterator that yields key-value pairs from a linked list.
847
- */
848
669
  *_getIterator() {
849
670
  let node = this.head;
850
671
  while (node !== this._sentinel) {
@@ -852,28 +673,20 @@ class LinkedHashMap extends base_1.IterableEntryBase {
852
673
  node = node.next;
853
674
  }
854
675
  }
855
- /**
856
- * Time Complexity: O(1)
857
- * Space Complexity: O(1)
858
- *
859
- * The `_deleteNode` function removes a node from a doubly linked list and updates the head and tail
860
- * pointers if necessary.
861
- * @param node - The `node` parameter is an instance of the `HashMapLinkedNode` class, which
862
- * represents a node in a linked list. It contains a key-value pair and references to the previous
863
- * and next nodes in the list.
864
- */
865
676
  _deleteNode(node) {
866
677
  const { prev, next } = node;
867
678
  prev.next = next;
868
679
  next.prev = prev;
869
- if (node === this.head) {
680
+ if (node === this.head)
870
681
  this._head = next;
871
- }
872
- if (node === this.tail) {
682
+ if (node === this.tail)
873
683
  this._tail = prev;
874
- }
875
684
  this._size -= 1;
876
685
  return true;
877
686
  }
687
+ _createLike(entries = [], options) {
688
+ const Ctor = this.constructor;
689
+ return new Ctor(entries, options);
690
+ }
878
691
  }
879
692
  exports.LinkedHashMap = LinkedHashMap;