ci sono dizionari in javascript come python?


100

ho bisogno di creare un dizionario in javascript come questo

non ricordo la notazione esatta, ma era qualcosa del tipo:

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

esiste una cosa del genere in javascript?



5
La risposta che hai accettato è molto sbagliata.
Esben Skov Pedersen

@EsbenSkovPedersen Quali errori hai notato in quella risposta?
Anderson Green

Vedo che è stato modificato dopo aver commentato. Sembra: mancava
Esben Skov Pedersen

2
Leggi la risposta più recente per le mappe ES6 stackoverflow.com/a/32993723/1993919 (commentando per lo stesso motivo per cui è stata pubblicata)
Old Badman Grey,

Risposte:


130

Questo è un vecchio post, ma ho pensato di dover fornire comunque una risposta illustrata.

Usa la notazione dell'oggetto di javascript. Così:

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

E per accedere ai valori:

states_dictionary.AK[0] //which is liza

oppure puoi usare la notazione dell'oggetto letterale javascript, per cui non è necessario che le chiavi siano tra virgolette:

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

11
vale la pena notare che il primo esempio dovrebbe produrre lo stesso oggetto in entrambi i linguaggi usando esattamente la stessa sintassi tranne il ';' di chiusura. states_dictionary = {"CT": ["alex", "harry"], "AK": ["liza", "alex"], "TX": ["fred", "harry"]}
Denis C

Sono più abituato alla notazione letterale degli oggetti, dal momento che vi si accede allo stesso modo qual è la differenza tra i due?
John Demetriou

2
@JohnDemetriou la differenza principale è che le chiavi di notazione degli oggetti javascript devono essere stringhe (racchiuse tra virgolette doppie ""). La notazione dell'oggetto è come si vede in JSON per l'interscambio di dati ed è stata ispirata dalla notazione dell'oggetto letterale; vale la pena notare che JSON viene solitamente utilizzato nel contesto delle stringhe
Capo

2
In realtà, Python consente il punto e virgola di terminazione delle istruzioni, quindi il primo esempio è completamente valido sia in Python che in JavaScript
celticminstrel

Se il valore proviene dall'utente, è necessario prestare attenzione nell'uso Object.hasOwnProperty.call(dictionary, key)(altrimenti l'utente può inserire un valore di valueOf e dictionary['valueOf']restituisce la Object.valueOf()funzione appartenente al prototipo dell'Oggetto che probabilmente non è ciò che il codice si aspetterebbe: potenziale bug o problema di sicurezza ). Se la chiave non è un tipo stringa, è necessario prestare attenzione, altrimenti le conversioni numeriche implicite e toString causeranno problemi. Il Maptipo ES6 è stato progettato per fornire funzionalità estese per i dizionari.
robocat

50

Non c'erano veri array associativi in ​​Javascript fino al 2015 (rilascio di ECMAScript 6). Da allora puoi usare l'oggetto Map come afferma Robocat. Cerca i dettagli in MDN . Esempio:

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

Senza il supporto per ES6 puoi provare a utilizzare gli oggetti:

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

Tuttavia, con gli oggetti non è possibile utilizzare proprietà o metodi di array tipici come array.length. Almeno è possibile accedere all '"array di oggetti" in un ciclo for-in.


3
E la performance? la ricerca di una chiave in un oggetto è a tempo costante?
Saher Ahwal

5
Poiché o ["key"] è equivalente a o.key in Javascript, le prestazioni sono quasi le stesse. Tuttavia le prestazioni dipendono dal motore Javascript / browser web. Ci sono molte differenze tra questi, specialmente nelle versioni precedenti.
Alex

ECMAScript 6 definisce un oggetto Map ufficiale (es. "Non ci sono array associativi reali in Javascript" non è corretto).
robocat

18

Mi rendo conto che questa è una vecchia domanda, ma viene visualizzata in Google quando cerchi "dizionari javascript", quindi vorrei aggiungere alle risposte precedenti che in ECMAScript 6 Mapè stato introdotto l'oggetto ufficiale , che è un dizionario implementazione:

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

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

A differenza dei normali oggetti di javascript, consente a qualsiasi oggetto come chiave:

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({});

Per me funziona, bello usare un metodo ES6 più pulito. Grazie! Follow up, de sappiamo un modo per "bulk set ()", ad esempio come Python dict = { key: value)?
Joe Sadoski

10

Ho creato un semplice dizionario in JS qui:

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";
        }
    }
}

L'implementazione di cui sopra può ora essere utilizzata per simulare un dizionario come:

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!"

Questa è solo una simulazione di base. Può essere ulteriormente ottimizzato implementando un algoritmo di tempo di esecuzione migliore per funzionare con una complessità temporale di almeno O (nlogn) o anche meno. Come merge / quick sort on arrays and then some B-search for lookups. Non ho provato o cercato di mappare una funzione hash in JS.

Inoltre, chiave e valore per l'oggetto JSdict possono essere trasformati in variabili private per essere subdoli.

Spero che questo ti aiuti!

MODIFICA >> Dopo aver implementato quanto sopra, ho utilizzato personalmente gli oggetti JS come array associativi disponibili immediatamente.

Tuttavia , vorrei fare una menzione speciale su due metodi che si sono effettivamente rivelati utili per renderlo una comoda esperienza di hashtable.

Vale a dire : dict.hasOwnProperty (chiave) ed elimina dict [chiave]

Leggi questo post come una buona risorsa su questa implementazione / utilizzo. Creazione dinamica di chiavi nell'array associativo JavaScript

Grazie!


5

Usa oggetti JavaScript. Puoi accedere alle loro proprietà come le chiavi in ​​un dizionario. Questa è la base di JSON. La sintassi è simile ai dizionari Python. Vedi: JSON.org


4

Una vecchia domanda ma di recente avevo bisogno di fare una porta AS3> JS e per motivi di velocità ho scritto un semplice oggetto Dictionary in stile AS3 per JS:

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

Se non lo sapevi, il dizionario AS3 ti consente di utilizzare qualsiasi oggetto come chiave, anziché solo stringhe. Sono molto utili una volta che hai trovato un uso per loro.

Non è veloce come sarebbe un oggetto nativo, ma non ho riscontrato alcun problema significativo al riguardo.

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
Libreria bella e utile! Ho aggiunto una funzione get, che pensavo mancasse e ho risolto alcuni problemi di sintassi minori (punto e virgola mancante ecc.). Ecco il violino modificato: Dizionario in JSFiddle
Matt

Bel lavoro amico, non so perché non c'era!
MickMalone1983

2

Firefox 13+ fornisce un'implementazione sperimentale mapdell'oggetto simile dictall'oggetto in Python. Specifiche qui .

È disponibile solo in Firefox, ma sembra migliore rispetto all'utilizzo degli attributi di un file new Object(). Citazione dalla documentazione:

  • Un oggetto ha un prototipo, quindi ci sono chiavi predefinite nella mappa. Tuttavia, questo può essere aggirato usando map = Object.create(null).
  • Le chiavi di un Objectsono Strings, dove possono essere qualsiasi valore per a Map.
  • Puoi ottenere Mapfacilmente la dimensione di un file mentre devi tenere traccia manualmente delle dimensioni per un file Object.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.