Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pythonic Nested default dictionary in javascript

Tags:

javascript

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!

like image 793
Michael P Avatar asked Mar 21 '26 16:03

Michael P


1 Answers

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.

like image 99
AKX Avatar answered Mar 24 '26 05:03

AKX



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!