есть ли словари в javascript, например python?

103

мне нужно сделать словарь в javascript вот так

я не помню точных обозначений, но это было что-то вроде:

states_dictionary={ CT=[alex,harry], AK=[liza,alex], TX=[fred, harry] ........ }

есть ли такое в javascript?

Алекс Гордон
источник
2
См. Этот вопрос: stackoverflow.com/questions/130543/…
Манодж Говиндан,
5
Вы приняли неправильный ответ.
Эсбен Сков Педерсен
@EsbenSkovPedersen Какие ошибки вы заметили в этом ответе?
Андерсон Грин
Я вижу, что это отредактировано после того, как я прокомментировал. Кажется: пропал без вести
Эсбен Сков Педерсен
2
Прочтите последний ответ для карт ES6 stackoverflow.com/a/32993723/1993919 (комментируя по той же причине, по которой он был опубликован)
Old Badman Gray

Ответы:

133

Это старый пост, но я подумал, что все равно должен дать иллюстрированный ответ.

Используйте обозначение объекта javascript. Вот так:

states_dictionary={ 
     "CT":["alex","harry"], 
     "AK":["liza","alex"], 
     "TX":["fred", "harry"]
};

И для доступа к значениям:

states_dictionary.AK[0] //which is liza

или вы можете использовать нотацию буквальных объектов javascript, при этом ключи не обязательно должны быть в кавычках:

states_dictionary={ 
     CT:["alex","harry"], 
     AK:["liza","alex"], 
     TX:["fred", "harry"]
};
Начальник
источник
12
Стоит отметить, что первый пример должен давать один и тот же объект на обоих языках с использованием одного и того же синтаксиса, за исключением закрывающего ';'. States_dictionary = {"CT": ["alex", "harry"], "AK": ["liza", "alex"], "TX": ["fred", "harry"]}
Денис C
Я больше привык к буквальной нотации объектов, поскольку вы обращаетесь к ним одинаково, в чем разница между ними?
Джон Деметриу
2
@JohnDemetriou основное отличие состоит в том, что ключи нотации объектов javascript должны быть строками (заключенными в двойные кавычки ""). Нотация объекта такая же, как в JSON для обмена данными, и была вдохновлена ​​буквальной нотацией объекта; стоит отметить, что JSON обычно используется в строковом контексте
Шеф,
2
На самом деле Python допускает точку с запятой в
конце
Если значение поступает от пользователя, то все равно должны быть приняты для использования Object.hasOwnProperty.call(dictionary, key)( в противном случае пользователь может ввести значение valueOf и dictionary['valueOf']возвращает Object.valueOf()функцию , принадлежащую к прототипу объекта , который, вероятно , не то , что ваш код будет ожидать - потенциальная ошибка или проблема безопасности ). Если ключ не является строковым типом, следует проявлять осторожность, иначе неявные числовые преобразования и преобразования toString вызовут проблемы. Тип ES6 Mapбыл разработан для обеспечения расширенной функциональности словарей.
robocat 04
54

До 2015 года (выпуск ECMAScript 6) в Javascript не было реальных ассоциативных массивов. С тех пор вы можете использовать объект Map как состояния Robocat. Подробности смотрите в MDN . Пример:

let map = new Map();
map.set('key', {'value1', 'value2'});
let values = map.get('key');

Без поддержки ES6 вы можете попробовать использовать объекты:

var x = new Object();
x["Key"] = "Value";

Однако с объектами невозможно использовать типичные свойства массива или методы, такие как array.length. По крайней мере, можно получить доступ к «массиву объектов» в цикле for.

Alex
источник
3
А что насчет производительности? ищет ключ в постоянном времени объекта?
Сахер Ахвал,
5
Поскольку o ["key"] эквивалентно o.key в Javascript, производительность почти такая же. Однако производительность зависит от Javascript Engine / Webbrowser. Между ними довольно много различий, особенно в старых версиях.
Alex
ECMAScript 6 определяет официальный объект Map (т.е. «В Javascript нет реальных ассоциативных массивов» теперь неверно).
robocat 04
18

Я понимаю, что это старый вопрос, но он появляется в Google, когда вы ищете «словари javascript», поэтому я хотел бы добавить к приведенным выше ответам, что в ECMAScript 6 Mapбыл введен официальный объект, который является словарем. реализация:

var dict = new Map();
dict.set("foo", "bar");

//returns "bar"
dict.get("foo");

В отличие от обычных объектов javascript, он позволяет использовать любой объект в качестве ключа:

var foo = {};
var bar = {};
var dict = new Map();
dict.set(foo, "Foo");
dict.set(bar, "Bar");

//returns "Bar"
dict.get(bar);

//returns "Foo"
dict.get(foo);

//returns undefined, as {} !== foo and {} !== bar
dict.get({});
Джимми Макгувер
источник
У меня работает, приятно использовать более чистый метод ES6. Спасибо! Следуйте дальше, знаем ли мы какой-нибудь способ "массового набора ()", например, как python dict = { key: value)?
Джо Садоски,
10

Здесь создали простой словарь на JS:

function JSdict() {
    this.Keys = [];
    this.Values = [];
}

// Check if dictionary extensions aren't implemented yet.
// Returns value of a key
if (!JSdict.prototype.getVal) {
    JSdict.prototype.getVal = function (key) {
        if (key == null) {
            return "Key cannot be null";
        }
        for (var i = 0; i < this.Keys.length; i++) {
            if (this.Keys[i] == key) {
                return this.Values[i];
            }
        }
        return "Key not found!";
    }
}


// Check if dictionary extensions aren't implemented yet.
// Updates value of a key
if (!JSdict.prototype.update) {
    JSdict.prototype.update = function (key, val) {
        if (key == null || val == null) {
            return "Key or Value cannot be null";
        }
        // Verify dict integrity before each operation
        if (keysLength != valsLength) {
            return "Dictionary inconsistent. Keys length don't match values!";
        }
        var keysLength = this.Keys.length;
        var valsLength = this.Values.length;
        var flag = false;
        for (var i = 0; i < keysLength; i++) {
            if (this.Keys[i] == key) {
                this.Values[i] = val;
                flag = true;
                break;
            }
        }
        if (!flag) {
            return "Key does not exist";
        }
    }
}



// Check if dictionary extensions aren't implemented yet.
// Adds a unique key value pair
if (!JSdict.prototype.add) {
    JSdict.prototype.add = function (key, val) {
        // Allow only strings or numbers as keys
        if (typeof (key) == "number" || typeof (key) == "string") {
            if (key == null || val == null) {
                return "Key or Value cannot be null";
            }
            if (keysLength != valsLength) {
                return "Dictionary inconsistent. Keys length don't match values!";
            }
            var keysLength = this.Keys.length;
            var valsLength = this.Values.length;
            for (var i = 0; i < keysLength; i++) {
                if (this.Keys[i] == key) {
                    return "Duplicate keys not allowed!";
                }
            }
            this.Keys.push(key);
            this.Values.push(val);
        }
        else {
            return "Only number or string can be key!";
        }
    }
}

// Check if dictionary extensions aren't implemented yet.
// Removes a key value pair
if (!JSdict.prototype.remove) {
    JSdict.prototype.remove = function (key) {
        if (key == null) {
            return "Key cannot be null";
        }
        if (keysLength != valsLength) {
            return "Dictionary inconsistent. Keys length don't match values!";
        }
        var keysLength = this.Keys.length;
        var valsLength = this.Values.length;
        var flag = false;
        for (var i = 0; i < keysLength; i++) {
            if (this.Keys[i] == key) {
                this.Keys.shift(key);
                this.Values.shift(this.Values[i]);
                flag = true;
                break;
            }
        }
        if (!flag) {
            return "Key does not exist";
        }
    }
}

Вышеупомянутая реализация теперь может использоваться для имитации словаря как:

var dict = new JSdict();

dict.add(1, "one")

dict.add(1, "one more")
"Duplicate keys not allowed!"

dict.getVal(1)
"one"

dict.update(1, "onne")

dict.getVal(1)
"onne"

dict.remove(1)

dict.getVal(1)
"Key not found!"

Это просто базовая симуляция. Его можно дополнительно оптимизировать, реализуя лучший алгоритм времени выполнения для работы с временной сложностью как минимум O (nlogn) или даже меньше. Например, слияние / быстрая сортировка по массивам, а затем некоторый B-поиск для поиска. Я не пробовал и не искал сопоставление хеш-функции в JS.

Кроме того, Key и Value для объекта JSdict можно превратить в частные переменные, чтобы они были скрытными.

Надеюсь это поможет!

РЕДАКТИРОВАТЬ >> После реализации вышеизложенного я лично использовал объекты JS как ассоциативные массивы, которые доступны «из коробки».

Тем не менее , я хотел бы особо упомянуть о двух методах, которые на самом деле оказались полезными, чтобы сделать хеш-таблицу удобным.

Визуализация : dict.hasOwnProperty (ключ) и удалить dict [ключ]

Прочтите этот пост как хороший ресурс по этой реализации / использованию. Динамическое создание ключей в ассоциативном массиве JavaScript

Благодарность!

Вайбхав
источник
5

Используйте объекты JavaScript. Вы можете получить доступ к их свойствам, таким как ключи в словаре. Это основа JSON. Синтаксис аналогичен словарям Python. См .: JSON.org

Адам
источник
4

Старый вопрос, но мне недавно нужно было сделать порт AS3> JS, и ради скорости я написал простой объект Dictionary в стиле AS3 для JS:

http://jsfiddle.net/MickMalone1983/VEpFf/2/

Если вы не знали, словарь AS3 позволяет использовать в качестве ключа любой объект, а не только строки. Они очень пригодятся, если вы нашли им применение.

Это не так быстро, как было бы с обычным объектом, но я не обнаружил у него серьезных проблем в этом отношении.

API:

//Constructor
var dict = new Dict(overwrite:Boolean);

//If overwrite, allows over-writing of duplicate keys,
//otherwise, will not add duplicate keys to dictionary.

dict.put(key, value);//Add a pair
dict.get(key);//Get value from key
dict.remove(key);//Remove pair by key
dict.clearAll(value);//Remove all pairs with this value
dict.iterate(function(key, value){//Send all pairs as arguments to this function:
    console.log(key+' is key for '+value);
});


dict.get(key);//Get value from key
MickMalone, 1983 ...
источник
1
Хорошая и полезная библиотека! Я добавил функцию get, которой, как мне казалось, не хватало, и исправил некоторые незначительные проблемы синтаксиса (отсутствие точки с запятой и т. Д.). Вот измененная скрипка: Словарь в JSFiddle
Мэтт
Хороший приятель, не знаю, почему его там не было!
MickMalone1983
2

Firefox 13+ предоставляет экспериментальную реализацию mapобъекта, аналогичную dictобъекту в python. Технические характеристики здесь .

Это доступно только в firefox, но выглядит лучше, чем использование атрибутов new Object(). Цитата из документации:

  • У объекта есть прототип, поэтому на карте есть ключи по умолчанию. Однако этого можно избежать, используя map = Object.create(null).
  • Ключи an Object- Stringsэто любое значение a Map.
  • Вы можете легко получить размер Mapфайла, в то время как вам придется вручную отслеживать размер файла Object.
Mquandalle
источник