I want to implement a nested default dictionary in javascript, so I can go
nest['first']['second']['third'] = 'yay'
without having to check or initialize nest['first'] & nest['first']['second']
In python, this is pretty easy
nested = defaultDict(lambda: deafultDict(dict()))
I tried to implement the same in javascript using Proxy. The results were not as expected and I can't figure out what I'm missing. From the last logline, it looks like the same default dictionary is being passed around as a reference. How can I avoid this and make it work as expected?
function defaultDict (defaultValue) {
const handler = {
get: (obj, prop) => {
return prop in obj ? obj[prop] : defaultValue
}
}
return new Proxy({}, handler)
}
var nested = defaultDict(defaultDict({}))
nested['first']['second']['third'] = 'yay'
console.log(nested['first']['second']['third']) // yay OK
console.log(nested['first']['second']) // {third: 'yay'} OK
console.log(nested['first']) // result: {} expected {second: {third: 'yay'}}
console.log(nested['none']['gggggggggggg']) // result: {third: 'yay'} expected: {}
thanks!
To achieve an arbitrarily deep autovivifying object, you'll want something like
function defaultDict(defaultValueFn) {
const handler = {
get: (obj, prop) => {
if(!(prop in obj)) obj[prop] = defaultValueFn();
return obj[prop];
},
};
return new Proxy({}, handler);
}
var nestedDefaultDict = () => defaultDict(nestedDefaultDict);
var nested = nestedDefaultDict();
nested.a.b.c = 8;
nested.d.e.f = 8;
console.log(nested); // { a: { b: { c: 8 } }, d: { e: { f: 8 } } }
, that is just like in the Python defaultdict, you pass in a callable that returns the nested object, not the object itself.
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