pythonic вложенный словарь по умолчанию в javascript

#javascript

#javascript

Вопрос:

Я хочу реализовать вложенный словарь по умолчанию в javascript, чтобы я мог перейти

nest['first']['second']['third'] = 'yay' без необходимости проверки или инициализации nest['first'] amp; nest['first']['second']

В python это довольно просто

 nested = defaultDict(lambda: deafultDict(dict()))
  

Я попытался реализовать то же самое в javascript с помощью прокси. Результаты оказались не такими, как ожидалось, и я не могу понять, чего мне не хватает. Из последней строки журнала похоже, что тот же словарь по умолчанию передается в качестве ссылки. Как я могу избежать этого и заставить его работать должным образом?

 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: {}
  

Спасибо!

Комментарии:

1. Ну, да, ваш самый внутренний {} in defaultDict(defaultDict({})) — это один простой объект.

2. конечно, но последняя строка журнала печатается {third: 'yay'} , а не {} так, как ожидалось

Ответ №1:

Чтобы получить произвольно глубокий объект автозаполнения, вам понадобится что-то вроде

 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 } } }
  

то есть, как и в Python defaultdict , вы передаете вызываемый объект, который возвращает вложенный объект, а не сам объект.

Комментарии:

1. к сожалению, это не дает мне ожидаемых результатов jsfiddle.net/6k8m1wth

2. Извините, исправлено. Я пропустил, что мы фактически не вставляли новый объект в прокси-объект.