I have a use case where I want to get an item from a Map
. If that item doesn’t exist, I want to insert an initial value and save it for later. I also would like to use const
variables so that I can’t accidentally rebind the local. I know I can write my own helper, but it seems to me that this pattern requires a lot of writing for a pattern which I expect to be quite common:
const item = myMap.has(key) ? myMap.get(key) : myMap.set(key, initialize()).get(key);
or to avoid the .get()
immediately after the .set()
:
const item = myMap.has(key) ? myMap.get(key) : (() => {const value = initialize(); myMap.set(key, value); return value})();
Is there a simpler way to get an item from a Map
into a const
variable and, if it doesn’t yet exist, insert an initial value for the key first?
I know that a similar question exists, but in that question there is no requirement that the inserted item be stored in a local after insertion and it uses let
rather than const
.
EDIT: I’ve gone with the utility function route and created maputil.
We can reduce it ever so slightly, factoring out the .get(key)
part:
const item = (myMap.has(key) ? myMap : myMap.set(key, initialize())).get(key);
...but I don't think we can go further without introducing a new function.
const initialize = _ => 42;
const myMap = new Map();
const key = "answer";
const item = (myMap.has(key) ? myMap : myMap.set(key, initialize())).get(key);
console.log(item);
console.log(Array.from(myMap.keys()));
So yeah, probably a candidate for a utility function. :-)
Standalone:
const getOrAdd = (map, key, initializer) => {
if (map.has(key)) {
return map.get(key);
}
const value = initializer();
map.set(key, value);
return value;
};
const initialize = _ => 42;
const myMap = new Map();
const key = "answer";
const item = getOrAdd(myMap, key, initialize);
console.log(item);
console.log(Array.from(myMap.keys()));
...or if you can extend builtins in your project (it's okay for some projects, not for others):
Object.defineProperty(Map.prototype, "getOrAdd", {
value: function(key, initializer) {
if (this.has(key)) {
return this.get(key);
}
const value = initializer();
this.set(key, value);
return value;
}
});
const initialize = _ => 42;
const myMap = new Map();
const key = "answer";
const item = myMap.getOrAdd(key, initialize);
console.log(item);
console.log(Array.from(myMap.keys()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With