Gibt es Wörterbücher in Javascript wie Python?

96

Ich muss ein Wörterbuch in Javascript wie dieses machen

Ich erinnere mich nicht an die genaue Notation, aber es war so etwas wie:

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

Gibt es so etwas in Javascript?

l - '' '' '' - '' '' '' '' '' '' ''
quelle
2
Siehe diese Frage: stackoverflow.com/questions/130543/…
Manoj Govindan
4
Die Antwort, die Sie akzeptiert haben, ist sehr falsch.
Esben Skov Pedersen
@EsbenSkovPedersen Welche Fehler haben Sie in dieser Antwort bemerkt?
Anderson Green
Ich sehe, dass es bearbeitet wird, nachdem ich kommentiert habe. Es scheint: fehlte
Esben Skov Pedersen
2
Lesen Sie die neueste Antwort für ES6 Maps stackoverflow.com/a/32993723/1993919 (Kommentar aus dem gleichen Grund, aus dem sie veröffentlicht wurde)
Old Badman Gray

Antworten:

128

Dies ist ein alter Beitrag, aber ich dachte, ich sollte trotzdem eine illustrierte Antwort geben.

Verwenden Sie die Objektnotation von Javascript. Wie so:

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

Und um auf die Werte zuzugreifen:

states_dictionary.AK[0] //which is liza

oder Sie können die Javascript-Literalobjektnotation verwenden, wobei die Schlüssel nicht in Anführungszeichen gesetzt werden müssen:

states_dictionary={ 
     CT:["alex","harry"], 
     AK:["liza","alex"], 
     TX:["fred", "harry"]
};
Chef
quelle
11
Es ist erwähnenswert, dass das erste Beispiel in beiden Sprachen dasselbe Objekt mit genau derselben Syntax liefern sollte, mit Ausnahme des schließenden ';'. States_Dictionary = {"CT": ["Alex", "Harry"], "AK": ["Liza", "Alex"], "TX": ["Fred", "Harry"]}
Denis C
Ich bin eher an die wörtliche Objektnotation gewöhnt, da Sie auf dieselbe Weise darauf zugreifen. Was ist der Unterschied zwischen den beiden?
John Demetriou
2
@ JohnDemetriou Der Hauptunterschied besteht darin, dass Javascript-Objektnotationsschlüssel Zeichenfolgen sein müssen (in doppelten Anführungszeichen "" eingeschlossen). Die Objektnotation entspricht der Darstellung in JSON für den Datenaustausch und wurde von der wörtlichen Objektnotation inspiriert. Es ist erwähnenswert, dass JSON normalerweise im String-Kontext verwendet wird
Chief
2
Tatsächlich erlaubt Python Semikolons zum Beenden von Anweisungen, sodass das erste Beispiel sowohl in Python als auch in JavaScript vollständig gültig ist
celticminstrel
Wenn der Wert vom Benutzer kommt, dann braucht Pflege Gebrauch genommen werden Object.hasOwnProperty.call(dictionary, key)(andernfalls der Benutzer einen Wert von eingeben valueOf und dictionary['valueOf']gibt die Object.valueOf()Funktion zum Objekt Prototyp gehört , das ist wahrscheinlich nicht das, was Ihr Code erwarten würde - potenzielle Fehler oder Sicherheitsproblem ). Wenn der Schlüssel kein Zeichenfolgentyp ist, muss vorsichtig vorgegangen werden, da sonst die impliziten numerischen und toString-Konvertierungen Probleme verursachen. Der ES6- MapTyp wurde entwickelt, um erweiterte Funktionen für Wörterbücher bereitzustellen.
Robocat
48

Bis 2015 (Veröffentlichung von ECMAScript 6) gab es in Javascript keine echten assoziativen Arrays. Seitdem können Sie das Map-Objekt als Robocat-Status verwenden. Schlagen Sie die Details in MDN nach . Beispiel:

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

Ohne Unterstützung für ES6 können Sie versuchen, Objekte zu verwenden:

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

Bei Objekten ist es jedoch nicht möglich, typische Array-Eigenschaften oder Methoden wie array.length zu verwenden. Zumindest ist es möglich, in einer for-in-Schleife auf das "Objekt-Array" zuzugreifen.

Alex
quelle
3
Was ist mit der Leistung? sucht ein Schlüssel in einer objektkonstanten Zeit?
Saher Ahwal
5
Da o ["key"] in Javascript o.key entspricht, ist die Leistung nahezu gleich. Die Leistung hängt jedoch von der Javascript Engine / dem Webbrowser ab. Es gibt ziemlich viele Unterschiede zwischen diesen, insbesondere in den älteren Versionen.
Alex
ECMAScript 6 definiert ein offizielles Map-Objekt (dh "Es gibt keine echten assoziativen Arrays in Javascript" ist jetzt falsch).
Robocat
18

Mir ist klar, dass dies eine alte Frage ist, die jedoch in Google angezeigt wird, wenn Sie nach "Javascript-Wörterbüchern" suchen. Daher möchte ich zu den obigen Antworten hinzufügen, dass in ECMAScript 6 das offizielle MapObjekt eingeführt wurde, bei dem es sich um ein Wörterbuch handelt Implementierung:

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

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

Im Gegensatz zu den normalen Objekten von Javascript ist jedes Objekt als Schlüssel zulässig:

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({});
JimmyMcHoover
quelle
Funktioniert für mich, schön eine sauberere ES6-Methode zu verwenden. Danke dir! Follow-up, wissen wir einen Weg zu "Bulk-Set ()", zB wie Python dict = { key: value)?
Joe Sadoski
10

Habe hier ein einfaches Wörterbuch in JS erstellt:

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

Die obige Implementierung kann nun verwendet werden, um ein Wörterbuch wie folgt zu simulieren:

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

Dies ist nur eine grundlegende Simulation. Es kann weiter optimiert werden, indem ein besserer Laufzeitalgorithmus implementiert wird, der in mindestens O (nlogn) Zeitkomplexität oder sogar weniger arbeitet. Wie Merge / Quick Sort auf Arrays und dann einige B-Suche nach Lookups. Ich habe nicht versucht oder nach dem Zuordnen einer Hash-Funktion in JS gesucht.

Außerdem können Schlüssel und Wert für das JSdict-Objekt in private Variablen umgewandelt werden, um hinterhältig zu sein.

Hoffe das hilft!

BEARBEITEN >> Nach der Implementierung des oben genannten habe ich die JS-Objekte persönlich als assoziative Arrays verwendet, die sofort verfügbar sind.

Aber ich würde gerne eine besondere Erwähnung über zwei Methoden machen , die tatsächlich hilfreich erwies es sich als eine bequeme hashtable Erlebnis zu machen.

Viz: dict.hasOwnProperty (Schlüssel) und lösche dict [Schlüssel]

Lesen Sie diesen Beitrag als gute Ressource für diese Implementierung / Verwendung. Dynamisches Erstellen von Schlüsseln im assoziativen JavaScript-Array

Vielen Dank!

Vaibhav
quelle
5

Verwenden Sie JavaScript-Objekte. Sie können auf ihre Eigenschaften wie Schlüssel in einem Wörterbuch zugreifen. Dies ist die Grundlage von JSON. Die Syntax ähnelt Python-Wörterbüchern. Siehe: JSON.org

Adam
quelle
4

Eine alte Frage, aber ich musste kürzlich einen AS3> JS-Port erstellen. Aus Gründen der Geschwindigkeit habe ich ein einfaches Dictionary-Objekt im AS3-Stil für JS geschrieben:

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

Wenn Sie es nicht wussten, können Sie im AS3-Wörterbuch jedes Objekt als Schlüssel verwenden, anstatt nur Zeichenfolgen. Sie sind sehr praktisch, wenn Sie eine Verwendung für sie gefunden haben.

Es ist nicht so schnell wie ein natives Objekt, aber ich habe in dieser Hinsicht keine wesentlichen Probleme damit festgestellt.

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
MickMalone1983
quelle
1
Schöne und nützliche Bibliothek! Ich habe eine get-Funktion hinzugefügt, die meiner Meinung nach fehlte, und einige kleinere Syntaxprobleme (fehlendes Semikolon usw.) behoben. Hier ist die modifizierte Geige: Wörterbuch in JSFiddle
Matt
Guter Job Kumpel, keine Ahnung, warum das nicht da war!
MickMalone1983
2

Firefox 13+ bietet eine experimentelle Implementierung des mapObjekts ähnlich dem dictObjekt in Python. Technische Daten hier .

Es ist nur in Firefox verfügbar, sieht aber besser aus als die Verwendung von Attributen von a new Object(). Zitat aus der Dokumentation:

  • Ein Objekt hat einen Prototyp, daher gibt es Standardschlüssel in der Karte. Dies kann jedoch mit umgangen werden map = Object.create(null).
  • Die Schlüssel von a Objectsind Strings, wo sie einen beliebigen Wert für a haben können Map.
  • Sie können die Größe eines Mapleicht ermitteln, während Sie die Größe für ein manuell verfolgen müssen Object.
mquandalle
quelle