#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. Ну, да, ваш самый внутренний
{}
indefaultDict(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. Извините, исправлено. Я пропустил, что мы фактически не вставляли новый объект в прокси-объект.