чи існують словники в javascript, такі як python?


100

мені потрібно зробити такий словник у javascript

я не пам’ятаю точних позначень, але це було приблизно так:

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

чи є таке в javascript?



5
Відповідь, яку ви прийняли, дуже неправильна.
Есбен Сков Педерсен,

@EsbenSkovPedersen Які помилки ви помітили у цій відповіді?
Anderson Green

Я бачу, що це редагується після того, як я прокоментував. Здається: пропав безвісти
Есбен Сков Педерсен

2
Читайте остання відповідь для ES6 Карти stackoverflow.com/a/32993723/1993919 (коментуючи ж причини була опублікована)
Старий Бедмена Gray

Відповіді:


130

Це стара публікація, але я подумав, що все-таки повинен надати ілюстровану відповідь.

Використовуйте нотацію об’єктів 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"]
};

11
Варто зазначити, що перший приклад повинен давати один і той же об’єкт в обох мовах із використанням абсолютно однакового синтаксису, за винятком завершального ';'. States_dictionary = {"CT": ["alex", "harry"], "AK": ["liza", "alex"], "TX": ["fred", "harry"]}
Денис С

Я більше звик до буквальної нотації об’єктів, оскільки ви отримуєте доступ до них однаково, у чому різниця між ними?
Джон Деметріу

2
@JohnDemetriou головна відмінність полягає в тому, що клавіші позначення об'єктів javascript повинні бути рядками (укладеними у подвійні лапки ""). Позначення об’єкта видно в JSON для обміну даними і натхнено буквальним позначенням об’єкта; Варто зазначити, що JSON зазвичай використовується в контексті рядків
начальник

2
Насправді, Python дозволяє
точку з

Якщо значення надходить від користувача, тоді слід подбати про використання Object.hasOwnProperty.call(dictionary, key)(інакше користувач може ввести значення valueOf і dictionary['valueOf']повертає Object.valueOf()функцію, що належить прототипу Object, що, ймовірно, не те, що очікував би ваш код - потенційна помилка або проблема безпеки ). Якщо ключ не є рядковим типом, тоді потрібно бути обережним, інакше неявні числові перетворення та перетворення toString викличуть у вас проблеми. Тип ES6 Mapрозроблений для забезпечення розширених функціональних можливостей словників.
robocat

50

Реальних асоціативних масивів у Javascript не було до 2015 року (випуск ECMAScript 6). Відтоді ви можете використовувати об'єкт 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-in-loop.


3
А як щодо виступу? шукає ключ у постійному часі об'єкта?
Saher Ahwal

5
Оскільки o ["ключ"] еквівалентно o.key у Javascript, продуктивність майже однакова. Однак продуктивність залежить від Javascript Engine / Webbrowser. Між ними є досить багато відмінностей, особливо в старих версіях.
Alex

ECMAScript 6 визначає офіційний об'єкт Карти (тобто "Зараз у Javascript немає справжніх асоціативних масивів" зараз неправильно).
robocat

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. Дякую! Подальші дії, чи знаємо ми будь-який спосіб "bulk set ()", наприклад, як 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.

Крім того, ключ і значення для JSdict obj можуть бути перетворені в приватні змінні, щоб бути підлим.

Сподіваюся, це допомагає!

РЕДАГУВАТИ >> Після реалізації вищезазначеного, я особисто використовував об'єкти JS як асоціативні масиви, які доступні нестандартно.

Однак я хотів би окремо згадати про два методи, які насправді виявились корисними, щоб зробити його зручним хеш-табличним досвідом.

Viz: dict.hasOwnProperty (ключ) і видалити dict [ключ]

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

Дякую!


5

Використовуйте об’єкти JavaScript. Ви можете отримати доступ до їх властивостей, як ключі у словнику. Це основа JSON. Синтаксис подібний до словників Python. Див .: JSON.org


4

Старе запитання, але нещодавно мені потрібно було зробити порт AS3> JS, і заради швидкості я написав простий об’єкт словника в стилі 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

1
Приємна та корисна бібліотека! Я додав функцію get, яка, на мою думку, була відсутня, та виправив незначні проблеми із синтаксисом (відсутність крапки з комою тощо). Ось модифікована скрипка: Словник у JSFiddle
Метт

Хороша робота, не знаю, чому цього там не було!
MickMalone1983

2

Firefox 13+ забезпечує експериментальну реалізацію mapоб'єкта, подібного до dictоб'єкта в python. Специфікації тут .

Це доступно лише у Firefox, але виглядає краще, ніж використання атрибутів a new Object(). Посилання з документації:

  • Об’єкт має прототип, тому на карті є ключі за замовчуванням. Однак це можна обійти за допомогою map = Object.create(null).
  • Ключі an Objectє Strings, де вони можуть мати будь-яке значення для a Map.
  • Ви можете легко отримати розмір, Mapпоки вам доведеться відстежувати розмір для Object.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.