Вот быстрый. По умолчанию Python действительно полезен:
from collections import defaultdict d = defaultdict(lambda: []) d['a'] += [1, 2, 3] d['a'] += [4] print(d['a']) # [1, 2, 3, 4] print(d['b']) # []
Пока не совсем удобно, вот быстрая версия JavaScript, используя полезную Карта Встроенный (который заставляет нас почти там):
module.exports = class DefaultMap extends Map { constructor(getDefaultValue, ...mapConstructorArgs) { super(mapConstructorArgs); if (typeof getDefaultValue !== 'function') { throw new Error('getDefaultValue must be a function'); } this.getDefaultValue = getDefaultValue; } get = key => { if (!this.has(key)) { this.set(key, this.getDefaultValue(key)); } return super.get(key); }; };
Вот как это использовать:
const DefaultMap = require('./DefaultMap'); const d = new DefaultMap(() => []); d.get('a').push(1, 2, 3); console.log(d.get('a')); // [1, 2, 3] console.log(d.get('b')); // []
Если вы хотите, чтобы значение по умолчанию должно быть зависимым от ключа, это легко:
const DefaultMap = require('./DefaultMap'); const d = new DefaultMap(key => (key < 10 ? 0 : 1)); d.set(5, d.get(5) + 1); d.set(20, d.get(20) + 1); console.log(d.get(5)); // 1 console.log(d.get(20)); // 2
И там у нас это есть.
Реализация с прокси
Если вы не любите .получить
Синтаксис, есть другой вариант, хотя я нахожу внедрение немного менее очевидно. Использует Прокси Отказ
Обратите внимание, что Прокси
не может быть использован с IE11, даже с Вавилом :
Неподдерживаемая функция
Из-за ограничений ES5 прокси нельзя трансформировать или полифиллировать. См. Поддержка в различных двигателях JavaScript.
module.exports = class DefaultDict extends Object { constructor(getDefaultValue, ...objectConstructorArgs) { super(objectConstructorArgs); if (typeof getDefaultValue !== 'function') { throw new Error('getDefaultValue must be a function'); } return new Proxy(this, { get: function(target, key) { if (!Reflect.has(target, key)) { Reflect.set(target, key, getDefaultValue(key)); } return Reflect.get(target, key); }, }); } };
Тогда вы можете использовать его так же, как родной объект:
const DefaultDict = require('./DefaultDict'); const d = new DefaultDict(() => []); d['a'].push(1, 2, 3); console.log(d['a']); // [1, 2, 3] console.log(d['b']); // []
Получить Код на Github Отказ
Оригинал: “https://dev.to/aaronmoat/implementing-python-s-defaultdict-in-javascript-1l6k”