graph-typed 2.0.5 → 2.1.0
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.
- package/dist/data-structures/base/iterable-element-base.d.ts +186 -83
- package/dist/data-structures/base/iterable-element-base.js +149 -107
- package/dist/data-structures/base/iterable-entry-base.d.ts +95 -119
- package/dist/data-structures/base/iterable-entry-base.js +59 -116
- package/dist/data-structures/base/linear-base.d.ts +250 -192
- package/dist/data-structures/base/linear-base.js +137 -274
- package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
- package/dist/data-structures/binary-tree/avl-tree-counter.js +171 -205
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +135 -87
- package/dist/data-structures/binary-tree/avl-tree.d.ts +138 -149
- package/dist/data-structures/binary-tree/avl-tree.js +208 -195
- package/dist/data-structures/binary-tree/binary-tree.d.ts +476 -632
- package/dist/data-structures/binary-tree/binary-tree.js +598 -869
- package/dist/data-structures/binary-tree/bst.d.ts +258 -306
- package/dist/data-structures/binary-tree/bst.js +505 -481
- package/dist/data-structures/binary-tree/red-black-tree.d.ts +107 -179
- package/dist/data-structures/binary-tree/red-black-tree.js +114 -209
- package/dist/data-structures/binary-tree/tree-counter.d.ts +132 -154
- package/dist/data-structures/binary-tree/tree-counter.js +172 -203
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
- package/dist/data-structures/binary-tree/tree-multi-map.js +105 -85
- package/dist/data-structures/graph/abstract-graph.d.ts +238 -233
- package/dist/data-structures/graph/abstract-graph.js +267 -237
- package/dist/data-structures/graph/directed-graph.d.ts +108 -224
- package/dist/data-structures/graph/directed-graph.js +146 -233
- package/dist/data-structures/graph/map-graph.d.ts +49 -55
- package/dist/data-structures/graph/map-graph.js +56 -59
- package/dist/data-structures/graph/undirected-graph.d.ts +103 -146
- package/dist/data-structures/graph/undirected-graph.js +129 -149
- package/dist/data-structures/hash/hash-map.d.ts +164 -338
- package/dist/data-structures/hash/hash-map.js +270 -457
- package/dist/data-structures/heap/heap.d.ts +214 -289
- package/dist/data-structures/heap/heap.js +340 -349
- package/dist/data-structures/heap/max-heap.d.ts +11 -47
- package/dist/data-structures/heap/max-heap.js +11 -66
- package/dist/data-structures/heap/min-heap.d.ts +12 -47
- package/dist/data-structures/heap/min-heap.js +11 -66
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
- package/dist/data-structures/linked-list/doubly-linked-list.js +368 -494
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +261 -310
- package/dist/data-structures/linked-list/singly-linked-list.js +447 -466
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +0 -107
- package/dist/data-structures/linked-list/skip-linked-list.js +0 -100
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
- package/dist/data-structures/priority-queue/max-priority-queue.js +11 -78
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
- package/dist/data-structures/priority-queue/min-priority-queue.js +10 -79
- package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -61
- package/dist/data-structures/priority-queue/priority-queue.js +8 -83
- package/dist/data-structures/queue/deque.d.ts +227 -254
- package/dist/data-structures/queue/deque.js +309 -348
- package/dist/data-structures/queue/queue.d.ts +180 -201
- package/dist/data-structures/queue/queue.js +265 -248
- package/dist/data-structures/stack/stack.d.ts +124 -102
- package/dist/data-structures/stack/stack.js +181 -125
- package/dist/data-structures/trie/trie.d.ts +164 -165
- package/dist/data-structures/trie/trie.js +189 -172
- package/dist/interfaces/binary-tree.d.ts +56 -6
- package/dist/interfaces/graph.d.ts +16 -0
- package/dist/types/data-structures/base/base.d.ts +1 -1
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -0
- package/dist/types/utils/utils.d.ts +1 -0
- package/dist/utils/utils.d.ts +1 -1
- package/dist/utils/utils.js +2 -1
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +238 -115
- package/src/data-structures/base/iterable-entry-base.ts +96 -120
- package/src/data-structures/base/linear-base.ts +271 -277
- package/src/data-structures/binary-tree/avl-tree-counter.ts +198 -216
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +192 -101
- package/src/data-structures/binary-tree/avl-tree.ts +239 -206
- package/src/data-structures/binary-tree/binary-tree.ts +664 -893
- package/src/data-structures/binary-tree/bst.ts +568 -570
- package/src/data-structures/binary-tree/red-black-tree.ts +161 -222
- package/src/data-structures/binary-tree/tree-counter.ts +199 -218
- package/src/data-structures/binary-tree/tree-multi-map.ts +131 -97
- package/src/data-structures/graph/abstract-graph.ts +339 -264
- package/src/data-structures/graph/directed-graph.ts +146 -236
- package/src/data-structures/graph/map-graph.ts +63 -60
- package/src/data-structures/graph/undirected-graph.ts +129 -152
- package/src/data-structures/hash/hash-map.ts +274 -496
- package/src/data-structures/heap/heap.ts +389 -402
- package/src/data-structures/heap/max-heap.ts +12 -76
- package/src/data-structures/heap/min-heap.ts +13 -76
- package/src/data-structures/linked-list/doubly-linked-list.ts +426 -530
- package/src/data-structures/linked-list/singly-linked-list.ts +495 -517
- package/src/data-structures/linked-list/skip-linked-list.ts +1 -108
- package/src/data-structures/priority-queue/max-priority-queue.ts +12 -87
- package/src/data-structures/priority-queue/min-priority-queue.ts +11 -88
- package/src/data-structures/priority-queue/priority-queue.ts +3 -92
- package/src/data-structures/queue/deque.ts +381 -357
- package/src/data-structures/queue/queue.ts +310 -264
- package/src/data-structures/stack/stack.ts +217 -131
- package/src/data-structures/trie/trie.ts +240 -175
- package/src/interfaces/binary-tree.ts +240 -6
- package/src/interfaces/graph.ts +37 -0
- package/src/types/data-structures/base/base.ts +5 -5
- package/src/types/data-structures/graph/abstract-graph.ts +5 -0
- package/src/types/utils/utils.ts +2 -0
- 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
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* @param entryOrRawElements -
|
|
64
|
-
*
|
|
65
|
-
* @
|
|
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
|
-
*
|
|
86
|
-
* @
|
|
87
|
-
*
|
|
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
|
-
*
|
|
94
|
-
* @
|
|
95
|
-
*
|
|
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
|
-
*
|
|
102
|
-
* @
|
|
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
|
-
*
|
|
109
|
-
* @
|
|
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
|
-
*
|
|
116
|
-
*
|
|
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
|
-
*
|
|
125
|
-
*
|
|
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
|
-
*
|
|
147
|
-
*
|
|
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
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
*
|
|
167
|
-
*
|
|
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
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
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
|
|
201
|
-
|
|
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
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
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
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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
|
-
*
|
|
281
|
-
*
|
|
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
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
* key
|
|
298
|
-
* @param
|
|
299
|
-
*
|
|
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
|
|
277
|
+
const out = this._createLike();
|
|
308
278
|
let index = 0;
|
|
309
|
-
for (const [key, value] of this)
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
* Time
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
*
|
|
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
|
|
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
|
-
|
|
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
|
-
*
|
|
342
|
-
*
|
|
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
|
-
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
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
|
-
*
|
|
395
|
-
* @
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
443
|
-
* @
|
|
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
|
-
*
|
|
450
|
-
* @
|
|
451
|
-
*
|
|
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
|
-
*
|
|
466
|
-
* @
|
|
467
|
-
*
|
|
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
|
-
*
|
|
474
|
-
* @
|
|
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
|
-
*
|
|
495
|
-
*
|
|
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
|
-
*
|
|
508
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
531
|
-
*
|
|
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
|
-
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
*
|
|
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);
|
|
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;
|
|
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
|
|
612
|
-
|
|
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
|
-
|
|
639
|
-
|
|
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
|
-
|
|
663
|
-
|
|
664
|
-
|
|
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
|
-
*
|
|
670
|
-
*
|
|
671
|
-
*
|
|
672
|
-
*
|
|
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;
|
|
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;
|
|
715
|
-
}
|
|
716
|
-
// Remove nodes from orgMap
|
|
581
|
+
if (!node)
|
|
582
|
+
return false;
|
|
717
583
|
delete this.noObjMap[hash];
|
|
718
584
|
}
|
|
719
|
-
|
|
720
|
-
this._deleteNode(node);
|
|
721
|
-
return true;
|
|
585
|
+
return this._deleteNode(node);
|
|
722
586
|
}
|
|
723
587
|
/**
|
|
724
|
-
*
|
|
725
|
-
*
|
|
726
|
-
*
|
|
727
|
-
*
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
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
|
|
782
|
-
|
|
783
|
-
|
|
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
|
|
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
|
-
|
|
809
|
-
}
|
|
644
|
+
if (predicate.call(thisArg, key, value, index, this))
|
|
645
|
+
out.set(key, value);
|
|
810
646
|
index++;
|
|
811
647
|
}
|
|
812
|
-
return
|
|
813
|
-
}
|
|
814
|
-
/**
|
|
815
|
-
*
|
|
816
|
-
*
|
|
817
|
-
*
|
|
818
|
-
*
|
|
819
|
-
*
|
|
820
|
-
* @param
|
|
821
|
-
*
|
|
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
|
|
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
|
-
|
|
664
|
+
out.set(newKey, newValue);
|
|
837
665
|
index++;
|
|
838
666
|
}
|
|
839
|
-
return
|
|
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;
|