3 ms·
Is there a proper way to use custom objects as keys in hashmaps in JS (well, ideally TypeScript compliant)? Coming out of the C++ world where this is trivial an
by arsome 5y ago
Is there a proper way to use custom objects as keys in hashmaps in JS (well, ideally TypeScript compliant)? Coming out of the C++ world where this is trivial and something I use quite often this seems pretty infuriating. Maybe a general data structure package that's worth pulling in?
EDIT: After doing a bit of research I found "tstl", looks interesting, their hashmap appears to support custom hashers and equality comparisons:
https://tstl.dev/api/classes/std.hashmap.html https://tstl.dev/api/classes/std.hashmap.html
I'm curious about experiences with it if anyone's had the chance?
- upzylon 5y agoIf the problem is just that you want to use non-primitive keys, that's what Maps are for. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- arsome 5y agoI'm aware of them, but the problem with that is you can only compare an object by instance if I recall correctly. There's no way to override the hashing and equality check that I could find, meaning even for simple objects you're basically forced to serialize your keys in some way still, which is disgustingly inefficient and slow for no good reason.
- doteka 5y agoSo much this. I remember being so excited that Map and Set were added to the language, only to find that they were worse than useless for objects. At least Set can be handy in a pinch, but I have never seen an actual usecase for Map that isn’t solved better with plain old JS objects. Curious if anyone else has?
- upzylon 5y agoThere definitely are valid use cases for a Map, and even more now that we have WeakMaps (e.g. associating data DOM nodes). Or mapping functions to values, e.g. something like this: const returnCache = new Map<() => any, any>() const memoized = <T extends () => any>(f: T): ReturnType<T> => { if (returnCache.has(f)) return returnCache.get(f) const v = f() returnCache.set(f, v) return v }
- gildas 5y ago> I have never seen an actual usecase for Map that isn’t solved better with plain old JS objects. Curious if anyone else has? With a Map, you can easily and efficiently associate data with DOM nodes without changing them.
- ErikCorry 5y agoA quick look at the source implies that that iteration order is not predictable.
- mediumdeviation 5y agoCreate a wrapper class that takes a stringifying function that converts the key objects into a primitive and use a Map<string, [K, V]> as the backing store. fast-json-stable-stringify can be used as the default stringifier, and if the objects are large or have a natural key a custom stringifier can also be supplied. Since we are using TS we can have our custom class implement Map<K, V>.
- arsome 5y agoThat's very similar to the solution I'm using and that I hate - it involves unnecessary generation and storage of strings and is far less ideal than something like the implementation in tstl I linked above where you can simply provide a custom hash function and equality comparison.