Implement value-semantic composite map keys with EncMap
mainIn JavaScript, standard objects only support string or number keys, and native Map objects compare objects by reference rather than value. To use composite types (vectors, lists, nested maps, sets) as keys where equality is determined by content (value-semantics), use the EncMap pattern.
EncMap works by encoding the composite key into a canonical string using a custom encoder and using that string as the key in a native js/Map. The value stored in the native map is an array [origKey, val], which allows for efficient iteration without decoding the keys.
class EncMap {
constructor(enc) {
this.m = new Map();
this.enc = enc || encKey;
}
set(k, v) {
this.m.set(this.enc(k), [k, v]);
return this;
}
get(k) {
const e = this.m.get(this.enc(k));
return e === undefined ? undefined : e[1];
}
has(k) {
return this.m.has(this.enc(k));
}
*keys() {
for (const e of this.m.values()) yield e[0];
}
}