Рубрики
Без рубрики

Реализация по умолчанию Python в JavaScript

Вот быстрый. По умолчанию Python по умолчанию действительно полезно: из коллекций Импортировать defaultdict d = … Помечено JavaScript, узел, Python.

Вот быстрый. По умолчанию 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”