0
# Maps & Associative Collections
1
2
Advanced mapping structures including bidirectional maps, multi-value maps, and fuzzy matching capabilities.
3
4
## Capabilities
5
6
### BiMap
7
8
Bidirectional map allowing efficient reverse lookups through inverse mapping.
9
10
```typescript { .api }
11
/**
12
* Bidirectional map with forward and inverse mappings
13
*/
14
function BiMap<K, V>(): BiMap<K, V>;
15
16
interface BiMap<K, V> extends Map<K, V> {
17
/** Access to the inverse map (value -> key) */
18
readonly inverse: InverseMap<V, K>;
19
20
/** Standard Map interface */
21
set(key: K, value: V): this;
22
get(key: K): V | undefined;
23
has(key: K): boolean;
24
delete(key: K): boolean;
25
clear(): void;
26
readonly size: number;
27
28
/** Standard iteration methods */
29
values(): IterableIterator<V>;
30
keys(): IterableIterator<K>;
31
entries(): IterableIterator<[K, V]>;
32
[Symbol.iterator](): IterableIterator<[K, V]>;
33
forEach(callback: (value: V, key: K, map: this) => void): void;
34
35
inspect(): any;
36
}
37
38
interface InverseMap<V, K> extends Map<V, K> {
39
/** Standard Map interface for reverse mapping */
40
get(value: V): K | undefined;
41
has(value: V): boolean;
42
// Other Map methods for value->key mapping
43
}
44
```
45
46
### MultiMap
47
48
Map allowing multiple values per key with configurable container type.
49
50
```typescript { .api }
51
/**
52
* Map allowing multiple values per key
53
* @param container Container constructor (Array or Set)
54
*/
55
function MultiMap<K, V>(container?: ArrayConstructor | SetConstructor): MultiMap<K, V>;
56
57
interface MultiMap<K, V> {
58
/** Number of unique keys */
59
readonly size: number;
60
/** Total number of key-value associations */
61
readonly dimension: number;
62
63
/** Add value to key's collection */
64
set(key: K, value: V): this;
65
66
/** Get all values for key */
67
get(key: K): Array<V> | Set<V> | undefined;
68
69
/** Check if key exists */
70
has(key: K): boolean;
71
72
/** Check if key has specific value */
73
hasValue(key: K, value: V): boolean;
74
75
/** Remove specific value from key */
76
remove(key: K, value: V): boolean;
77
78
/** Remove all values for key */
79
delete(key: K): boolean;
80
81
/** Remove all key-value pairs */
82
clear(): void;
83
84
/** Get number of values for key */
85
multiplicity(key: K): number;
86
87
/** Iterate over all key-value associations */
88
forEachAssociation(callback: (value: V, key: K) => void): void;
89
90
/** Standard iteration over keys */
91
keys(): IterableIterator<K>;
92
values(): IterableIterator<Array<V> | Set<V>>;
93
entries(): IterableIterator<[K, Array<V> | Set<V>]>;
94
[Symbol.iterator](): IterableIterator<[K, Array<V> | Set<V>]>;
95
96
inspect(): any;
97
}
98
```
99
100
### DefaultMap
101
102
Map that creates default values for missing keys using a factory function.
103
104
```typescript { .api }
105
/**
106
* Map with automatic default value creation
107
* @param factory Function to create default values
108
*/
109
function DefaultMap<K, V>(factory: () => V): DefaultMap<K, V>;
110
111
interface DefaultMap<K, V> extends Map<K, V> {
112
/** Get value or create default if key doesn't exist */
113
get(key: K): V;
114
115
/** Standard Map interface */
116
set(key: K, value: V): this;
117
has(key: K): boolean;
118
delete(key: K): boolean;
119
clear(): void;
120
readonly size: number;
121
122
values(): IterableIterator<V>;
123
keys(): IterableIterator<K>;
124
entries(): IterableIterator<[K, V]>;
125
[Symbol.iterator](): IterableIterator<[K, V]>;
126
forEach(callback: (value: V, key: K, map: this) => void): void;
127
128
inspect(): any;
129
}
130
```
131
132
### FuzzyMap
133
134
Map with fuzzy string matching using configurable distance function and tolerance.
135
136
```typescript { .api }
137
/**
138
* Map with fuzzy string matching
139
* @param distance Distance function for string comparison
140
* @param tolerance Maximum distance for matches
141
*/
142
function FuzzyMap<V>(distance: DistanceFunction, tolerance: number): FuzzyMap<V>;
143
144
interface FuzzyMap<V> {
145
readonly size: number;
146
147
/** Set key-value pair */
148
set(key: string, value: V): this;
149
150
/** Get value with fuzzy matching */
151
get(key: string): V | undefined;
152
153
/** Check if fuzzy match exists */
154
has(key: string): boolean;
155
156
/** Delete exact key */
157
delete(key: string): boolean;
158
159
/** Remove all entries */
160
clear(): void;
161
162
values(): IterableIterator<V>;
163
keys(): IterableIterator<string>;
164
entries(): IterableIterator<[string, V]>;
165
[Symbol.iterator](): IterableIterator<[string, V]>;
166
167
inspect(): any;
168
}
169
170
type DistanceFunction = (a: string, b: string) => number;
171
```
172
173
### FuzzyMultiMap
174
175
MultiMap with fuzzy string matching capabilities.
176
177
```typescript { .api }
178
/**
179
* MultiMap with fuzzy string matching
180
* @param distance Distance function for string comparison
181
* @param tolerance Maximum distance for matches
182
*/
183
function FuzzyMultiMap<V>(distance: DistanceFunction, tolerance: number): FuzzyMultiMap<V>;
184
185
interface FuzzyMultiMap<V> {
186
readonly size: number;
187
readonly dimension: number;
188
189
/** Add value with fuzzy key matching */
190
set(key: string, value: V): this;
191
192
/** Get all values with fuzzy key matching */
193
get(key: string): Array<V> | undefined;
194
195
/** Check if fuzzy match exists */
196
has(key: string): boolean;
197
198
/** Remove specific value with fuzzy matching */
199
remove(key: string, value: V): boolean;
200
201
/** Delete all values for fuzzy-matched key */
202
delete(key: string): boolean;
203
204
clear(): void;
205
206
/** Iterate over all associations */
207
forEachAssociation(callback: (value: V, key: string) => void): void;
208
209
keys(): IterableIterator<string>;
210
values(): IterableIterator<Array<V>>;
211
entries(): IterableIterator<[string, Array<V>]>;
212
213
inspect(): any;
214
}
215
```
216
217
### DefaultWeakMap
218
219
WeakMap with default value factory for missing keys.
220
221
```typescript { .api }
222
/**
223
* WeakMap with automatic default value creation
224
* @param factory Function to create default values
225
*/
226
function DefaultWeakMap<K extends object, V>(factory: () => V): DefaultWeakMap<K, V>;
227
228
interface DefaultWeakMap<K extends object, V> extends WeakMap<K, V> {
229
/** Get value or create default if key doesn't exist */
230
get(key: K): V;
231
232
/** Standard WeakMap interface */
233
set(key: K, value: V): this;
234
has(key: K): boolean;
235
delete(key: K): boolean;
236
}
237
```
238
239
## Usage Examples
240
241
### BiMap Example
242
243
```typescript
244
import {BiMap} from "mnemonist";
245
246
const userMap = new BiMap<number, string>();
247
userMap.set(123, "alice");
248
userMap.set(456, "bob");
249
250
// Forward lookup
251
console.log(userMap.get(123)); // "alice"
252
253
// Reverse lookup
254
console.log(userMap.inverse.get("alice")); // 123
255
console.log(userMap.inverse.has("bob")); // true
256
```
257
258
### MultiMap Example
259
260
```typescript
261
import {MultiMap} from "mnemonist";
262
263
// Array-based multimap
264
const tags = new MultiMap<string, string>(Array);
265
tags.set("javascript", "async");
266
tags.set("javascript", "promises");
267
tags.set("javascript", "closures");
268
269
console.log(tags.get("javascript")); // ["async", "promises", "closures"]
270
console.log(tags.multiplicity("javascript")); // 3
271
272
// Set-based multimap (no duplicates)
273
const categories = new MultiMap<string, string>(Set);
274
categories.set("frontend", "react");
275
categories.set("frontend", "vue");
276
categories.set("frontend", "react"); // Duplicate ignored in Set
277
278
console.log(categories.get("frontend")); // Set(2) {"react", "vue"}
279
```
280
281
### DefaultMap Example
282
283
```typescript
284
import {DefaultMap} from "mnemonist";
285
286
// Counter using default map
287
const counter = new DefaultMap<string, number>(() => 0);
288
counter.set("apple", counter.get("apple") + 1); // Creates 0, then sets to 1
289
counter.set("apple", counter.get("apple") + 1); // Increments to 2
290
291
// Grouping with default arrays
292
const groups = new DefaultMap<string, Array<any>>(() => []);
293
groups.get("fruits").push("apple");
294
groups.get("fruits").push("banana");
295
groups.get("vegetables").push("carrot");
296
```
297
298
### FuzzyMap Example
299
300
```typescript
301
import {FuzzyMap} from "mnemonist";
302
303
// Using Levenshtein distance for fuzzy matching
304
function levenshtein(a: string, b: string): number {
305
// Implementation of edit distance
306
return /* calculated distance */;
307
}
308
309
const fuzzyMap = new FuzzyMap<string>(levenshtein, 2);
310
fuzzyMap.set("javascript", "JS programming language");
311
fuzzyMap.set("python", "Python programming language");
312
313
// Fuzzy lookups
314
console.log(fuzzyMap.get("javascrip")); // Matches "javascript" (distance 1)
315
console.log(fuzzyMap.get("Java")); // No match (distance > 2)
316
console.log(fuzzyMap.has("pythom")); // true (matches "python")
317
```
318
319
## Performance Characteristics
320
321
| Operation | BiMap | MultiMap | DefaultMap | FuzzyMap |
322
|-----------|-------|----------|------------|----------|
323
| Get | O(1) | O(1) | O(1) | O(n·d) |
324
| Set | O(1) | O(1) | O(1) | O(1) |
325
| Delete | O(1) | O(k) | O(1) | O(1) |
326
| Has | O(1) | O(1) | O(1) | O(n·d) |
327
| Space | O(n) | O(n+m) | O(n) | O(n) |
328
329
Where:
330
- n = number of keys
331
- m = total number of key-value associations (MultiMap)
332
- k = average values per key (MultiMap)
333
- d = average string length (FuzzyMap distance calculation)
334
335
## Choosing the Right Map
336
337
- **BiMap**: When you need efficient reverse lookups
338
- **MultiMap**: When keys can have multiple values
339
- **DefaultMap**: When you want automatic creation of missing values
340
- **FuzzyMap**: For approximate string matching scenarios
341
- **DefaultWeakMap**: For object-keyed maps with garbage collection and defaults