Как сделать ассоциативный массив / хеширование в JavaScript



Answers

var associativeArray = {};
associativeArray["one"] = "First";
associativeArray["two"] = "Second";
associativeArray["three"] = "Third";

Если вы исходите из объектно-ориентированного языка, вы должны проверить эту статью .

Question

Я хочу рассчитать / сохранить некоторую статистическую информацию с помощью JavaScript, эквивалентный код на C # ниже (мне нужны функции - пара ключ-значение, пара значений ключа строки / int, манипулирование значениями по ключам и т. Д.), Любые идеи о том, как реализовать ту же функцию в JavaScript? Похоже, нет встроенного словаря или Hashtable?

Dictionary<string, int> statistics;

statistics["Foo"] = 10;
statistics["Goo"] = statistics["Goo"] + 1;
statistics.Add("Zoo", 1);



Все современные браузеры поддерживают объект javascript Map . Есть несколько причин, которые делают использование карты лучше, чем Object:

  • Объект имеет прототип, поэтому на карте есть ключи по умолчанию.
  • Ключами объекта являются строки, где они могут быть любым значением для Карты.
  • Вы можете легко получить размер карты, в то время как вам нужно отслеживать размер объекта.

Пример:

var myMap = new Map();

var keyObj = {},
    keyFunc = function () {},
    keyString = "a string";

myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

myMap.size; // 3

myMap.get(keyString);    // "value associated with 'a string'"
myMap.get(keyObj);       // "value associated with keyObj"
myMap.get(keyFunc);      // "value associated with keyFunc"

Если вы хотите, чтобы ключи, на которые не ссылались другие объекты, которые собирали мусор, рассмотрите возможность использования карты WeakMap вместо карты.




Если вам нужно, чтобы ваши ключи были любыми объектами, а не просто строками, вы могли бы использовать мою jshashtable .




Я создал это для решения некоторых проблем, таких как сопоставление ключей объектов, способность перечисления (с методом forEach() ) и очистки.

function Hashtable() {
    this._map = new Map();
    this._indexes = new Map();
    this._keys = [];
    this._values = [];
    this.put = function(key, value) {
        var newKey = !this.containsKey(key);
        this._map.set(key, value);
        if (newKey) {
            this._indexes.set(key, this.length);
            this._keys.push(key);
            this._values.push(value);
        }
    };
    this.remove = function(key) {
        if (!this.containsKey(key))
            return;
        this._map.delete(key);
        var index = this._indexes.get(key);
        this._indexes.delete(key);
        this._keys.splice(index, 1);
        this._values.splice(index, 1);
    };
    this.indexOfKey = function(key) {
        return this._indexes.get(key);
    };
    this.indexOfValue = function(value) {
        return this._values.indexOf(value) != -1;
    };
    this.get = function(key) {
        return this._map.get(key);
    };
    this.entryAt = function(index) {
        var item = {};
        Object.defineProperty(item, "key", {
            value: this.keys[index],
            writable: false
        });
        Object.defineProperty(item, "value", {
            value: this.values[index],
            writable: false
        });
        return item;
    };
    this.clear = function() {
        var length = this.length;
        for (var i = 0; i < length; i++) {
            var key = this.keys[i];
            this._map.delete(key);
            this._indexes.delete(key);
        }
        this._keys.splice(0, length);
    };
    this.containsKey = function(key) {
        return this._map.has(key);
    };
    this.containsValue = function(value) {
        return this._values.indexOf(value) != -1;
    };
    this.forEach = function(iterator) {
        for (var i = 0; i < this.length; i++)
            iterator(this.keys[i], this.values[i], i);
    };
    Object.defineProperty(this, "length", {
        get: function() {
            return this._keys.length;
        }
    });
    Object.defineProperty(this, "keys", {
        get: function() {
            return this._keys;
        }
    });
    Object.defineProperty(this, "values", {
        get: function() {
            return this._values;
        }
    });
    Object.defineProperty(this, "entries", {
        get: function() {
            var entries = new Array(this.length);
            for (var i = 0; i < entries.length; i++)
                entries[i] = this.entryAt(i);
            return entries;
        }
    });
}


Документация класса Hashtable

Методы:

  • get(key)
    Возвращает значение, связанное с указанным ключом.
    Параметры:
    key : ключ, из которого извлекается значение.

  • put(key, value)
    Связывает указанное значение с указанным ключом.
    Параметры:
    key : ключ, к которому привязывает значение.
    value : значение для привязки к ключу.

  • remove(key)
    Удаляет указанный ключ со своим значением.
    Параметры:
    key : Ключ для удаления.

  • clear()
    Очищает всю хэш-таблицу, удаляя как ключи, так и значения.

  • indexOfKey(key)
    Возвращает индекс указанного ключа, основываясь на порядке добавления.
    Параметры:
    key : ключ к которому получает индекс.

  • indexOfValue(value)
    Возвращает индекс указанного значения в соответствии с порядком добавления.
    Параметры:
    value : значение которого получает индекс.
    Заметки:
    Эта информация извлекается методом indexOf() для массива, поэтому он сравнивает объект только с методом toString() .

  • entryAt(index)
    Возвращает объект с двумя свойствами: ключ и значение, представляющий запись в указанном индексе.
    Параметры:
    index : индекс записи.

  • containsKey(key)
    Возвращает, содержит ли хэш-таблицу указанный ключ.
    Параметры:
    key : ключ для проверки.

  • containsValue(value)
    Возвращает, содержит ли хэш-таблица указанное значение.
    Параметры:
    value : значение для проверки.

  • forEach(iterator)
    Итерирует все записи в указанном iterator .
    Параметры:
    value : метод с тремя параметрами: key , value и index , где index представляет индекс записи.

    Свойства:

  • length ( только для чтения )
    Возвращает количество записей в хэш-таблице.

  • ( только для чтения )
    Получает массив всех ключей в хэш-таблице.

  • values ( только для чтения )
    Получает массив всех значений в хэш-таблице.

  • entries ( только для чтения )
    Получает массив всех записей в хэш-таблице. Они представлены в той же форме метода entryAt() .




function HashTable() {
    this.length = 0;
    this.items = new Array();
    for (var i = 0; i < arguments.length; i += 2) {
        if (typeof (arguments[i + 1]) != 'undefined') {
            this.items[arguments[i]] = arguments[i + 1];
            this.length++;
        }
    }

    this.removeItem = function (in_key) {
        var tmp_previous;
        if (typeof (this.items[in_key]) != 'undefined') {
            this.length--;
            var tmp_previous = this.items[in_key];
            delete this.items[in_key];
        }

        return tmp_previous;
    }

    this.getItem = function (in_key) {
        return this.items[in_key];
    }

    this.setItem = function (in_key, in_value) {
        var tmp_previous;
        if (typeof (in_value) != 'undefined') {
            if (typeof (this.items[in_key]) == 'undefined') {
                this.length++;
            } else {
                tmp_previous = this.items[in_key];
            }

            this.items[in_key] = in_value;
        }

        return tmp_previous;
    }

    this.hasItem = function (in_key) {
        return typeof (this.items[in_key]) != 'undefined';
    }

    this.clear = function () {
        for (var i in this.items) {
            delete this.items[i];
        }

        this.length = 0;
    }
}



Links