-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhashed-map.0.ts
More file actions
56 lines (55 loc) · 1.79 KB
/
hashed-map.0.ts
File metadata and controls
56 lines (55 loc) · 1.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import { inspect } from 'node:util';
/** Wrapper around Map which stores the original key as part of the Map's value, so there is no unpacking overhead */
// `implements Map<Key, Value>` is helpful to verify the shape of the class but it cannot actually be satisfied
export class HashedMap<Key, Value, Hash = string | number | bigint> {
#map: Map<Hash, { key: Key; value: Value }>;
constructor(
public readonly hasher: (key: Key) => Hash,
iterable?: Iterable<[Key, Value]>,
hashedIterable?: Iterable<[Hash, { key: Key; value: Value }]>,
) {
this.#map = new Map<Hash, { key: Key; value: Value }>(
iterable ? [...iterable].map(([key, value]) => [hasher(key), { key, value }]) : hashedIterable ?? null,
);
}
clear() {
return this.#map.clear();
}
delete(key: Key) {
return this.#map.delete(this.hasher(key));
}
entries(): MapIterator<[Key, Value]> {
return this.#map.values().map(({ key, value }) => [key, value]);
}
forEach(callback: (value: Value, key: Key, hashedMap: this) => void) {
return this.#map.values().forEach(({ key, value }) => callback(value, key, this));
}
get(key: Key) {
return this.#map.get(this.hasher(key))?.value;
}
has(key: Key) {
return this.#map.has(this.hasher(key));
}
keys(): MapIterator<Key> {
return this.#map.values().map(({ key }) => key);
}
set(key: Key, value: Value) {
this.#map.set(this.hasher(key), { key, value });
return this;
}
get size() {
return this.#map.size;
}
values(): MapIterator<Value> {
return this.#map.values().map(({ value }) => value);
}
clone(): HashedMap<Key, Value, Hash> {
return new HashedMap(this.hasher, undefined, this.#map);
}
[Symbol.iterator]() {
return this.entries();
}
[inspect.custom]() {
return this.entries().toArray();
}
}