Dynamisches Erstellen von Schlüsseln im assoziativen JavaScript-Array

199

Wie kann ich dynamisch Schlüssel in assoziativen Javascript-Arrays erstellen?

Die gesamte Dokumentation, die ich bisher gefunden habe, besteht darin, bereits erstellte Schlüssel zu aktualisieren:

 arr['key'] = val;

Ich habe so eine Schnur " name = oscar "

Und ich möchte mit so etwas enden:

{ name: 'whatever' }

Das heißt, ich teile die Zeichenfolge und erhalte das erste Element, und ich möchte das in ein Wörterbuch einfügen.

Code

var text = ' name = oscar '
var dict = new Array();
var keyValuePair = text.split(' = ');
dict[ keyValuePair[0] ] = 'whatever';
alert( dict ); // prints nothing.
OscarRyz
quelle
24
Wechseln Sie

Antworten:

142

Verwenden Sie das erste Beispiel. Wenn der Schlüssel nicht vorhanden ist, wird er hinzugefügt.

var a = new Array();
a['name'] = 'oscar';
alert(a['name']);

Öffnet ein Meldungsfeld mit 'oscar'.

Versuchen:

var text = 'name = oscar'
var dict = new Array()
var keyValuePair = text.replace(/ /g,'').split('=');
dict[ keyValuePair[0] ] = keyValuePair[1];
alert( dict[keyValuePair[0]] );
Tvanfosson
quelle
Ich habe das als Beispiel in Firefox ausgeführt, nur um sicherzugehen. Haben Sie sichergestellt, dass "Name" in Anführungszeichen gesetzt wird?
Tvanfosson
1
Ähm, nein, weil ich den Schlüssel "dynamisch" und nicht statisch erstelle. Lassen Sie mich trotzdem noch einmal
überprüfen
2
Bitte beziehen Sie sich auf Dannys ausführlichere Erklärung. Sie können nicht auf die Array-Werte in einer for-Schleife mit einem Index verweisen (z. B. myarray [i]). Hoffe das ist nicht zu verwirrend.
MK_Dev
4
Noch besser ist es, ein Objekt (Klammer {} -Notation) zu verwenden, um den Aufwand für .length, .slice () usw. zu vermeiden, die im Array-Prototyp enthalten sind
bjornl
488

Irgendwie sind alle Beispiele, obwohl sie gut funktionieren, überkompliziert:

  • Sie verwenden new Array(), was ein Overkill (und ein Overhead) für ein einfaches assoziatives Array (AKA-Wörterbuch) ist.
  • Die besseren benutzen new Object(). Funktioniert gut, aber warum all diese zusätzlichen Eingaben?

Diese Frage ist mit "Anfänger" gekennzeichnet. Machen wir es uns einfach.

Die überaus einfache Möglichkeit, ein Wörterbuch in JavaScript zu verwenden oder "Warum hat JavaScript kein spezielles Wörterbuchobjekt?":

// create an empty associative array (in JavaScript it is called ... Object)
var dict = {};   // huh? {} is a shortcut for "new Object()"

// add a key named fred with value 42
dict.fred = 42;  // we can do that because "fred" is a constant
                 // and conforms to id rules

// add a key named 2bob2 with value "twins!"
dict["2bob2"] = "twins!";  // we use the subscript notation because
                           // the key is arbitrary (not id)

// add an arbitrary dynamic key with a dynamic value
var key = ..., // insanely complex calculations for the key
    val = ...; // insanely complex calculations for the value
dict[key] = val;

// read value of "fred"
val = dict.fred;

// read value of 2bob2
val = dict["2bob2"];

// read value of our cool secret key
val = dict[key];

Ändern wir nun die Werte:

// change the value of fred
dict.fred = "astra";
// the assignment creates and/or replaces key-value pairs

// change value of 2bob2
dict["2bob2"] = [1, 2, 3];  // any legal value can be used

// change value of our secret key
dict[key] = undefined;
// contrary to popular beliefs assigning "undefined" does not remove the key

// go over all keys and values in our dictionary
for (key in dict) {
  // for-in loop goes over all properties including inherited properties
  // let's use only our own properties
  if (dict.hasOwnProperty(key)) {
    console.log("key = " + key + ", value = " + dict[key]);
  }
}

Das Löschen von Werten ist ebenfalls einfach:

// let's delete fred
delete dict.fred;
// fred is removed, the rest is still intact

// let's delete 2bob2
delete dict["2bob2"];

// let's delete our secret key
delete dict[key];

// now dict is empty

// let's replace it, recreating all original data
dict = {
  fred:    42,
  "2bob2": "twins!"
  // we can't add the original secret key because it was dynamic,
  // we can only add static keys
  // ...
  // oh well
  temp1:   val
};
// let's rename temp1 into our secret key:
if (key != "temp1") {
  dict[key] = dict.temp1; // copy the value
  delete dict.temp1;      // kill the old key
} else {
  // do nothing, we are good ;-)
}
Eugene Lazutkin
quelle
2
Hallo, ich weiß, dass ich auf die alte Antwort antworte, aber sie hat bei Google einen hohen Stellenwert, daher werde ich trotzdem fragen. Ich bin etwas verwirrt darüber, was in Ihrem Beispiel bedeutet, dass "wir den ursprünglichen geheimen Schlüssel nicht hinzufügen können, weil er dynamisch war, wir können nur statische Schlüssel hinzufügen".
Karel Bílek
1
Es bedeutet genau das, was es sagt: Wir kennen seinen Wert nicht und können ihn daher nicht als Konstante darstellen, was bei der Angabe eines Schlüssels in einem Objektliteral erforderlich ist.
Eugene Lazutkin
3
"Wir können den ursprünglichen geheimen Schlüssel nicht hinzufügen, weil er dynamisch war" ist an sich nicht korrekt, obwohl Sie eine Variable nicht als Schlüssel direkt in {} oder als Schlüssel mit Punktnotation verwenden können. Wir können weiterhin einen dynamischen Schlüssel über "dict [key] = val" hinzufügen, wie Sie zu Beginn des Beispiels zeigen. Die Einschränkung besteht darin, die {} -Notation anstelle des Schlüssels selbst zu verwenden.
Zut
8
Dies sieht aus wie Sheldon Coopers Antwort :)
jpatiaga
4
perfekte vollständige Antwort, sollte die Standardeinstellung sein
Dennis Golomazov
29

Javascript hat keine assoziativen Arrays , sondern Objekte .

Die folgenden Codezeilen machen alle genau dasselbe - setzen Sie das Feld 'name' für ein Objekt auf 'orion'.

var f = new Object(); f.name = 'orion';
var f = new Object(); f['name'] = 'orion';
var f = new Array(); f.name = 'orion';
var f = new Array(); f['name'] = 'orion';
var f = new XMLHttpRequest(); f['name'] = 'orion';

Es sieht so aus, als hätten Sie ein assoziatives Array, weil ein Arrayauch ein ist Object- obwohl Sie dem Array überhaupt keine Dinge hinzufügen, setzen Sie Felder für das Objekt.

Nachdem dies geklärt ist, finden Sie hier eine funktionierende Lösung für Ihr Beispiel

var text = '{ name = oscar }'
var dict = new Object();

// Remove {} and spaces
var cleaned = text.replace(/[{} ]/g, '');

// split into key and value
var kvp = cleaned.split('=');

// put in the object
dict[ kvp[0] ] = kvp[1];
alert( dict.name ); // prints oscar.
Orion Edwards
quelle
Angenommen, die Textzeichenfolge hat tatsächlich geschweifte Klammern, könnten Sie sie mehr oder weniger als JSON behandeln. Ersetzen Sie das = -Zeichen durch ein: und Sie müssen ein Objekt
auswerten
1
Hoppla, die Zeichenfolge ist nicht richtig abgegrenzt. Nichts, was Regex nicht reparieren kann.
Neonski
9

In Reaktion auf MK_Dev kann man iterieren, aber nicht nacheinander. (Dafür wird natürlich ein Array benötigt)

Die schnelle Google-Suche zeigt Hash-Tabellen in Javascript an

Beispielcode für das Durchlaufen von Werten in einem Hash (über den oben genannten Link):

var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;

// show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}
Danny
quelle
5

Originalcode (Ich habe die Zeilennummern hinzugefügt, damit ich darauf verweisen kann):

1  var text = ' name = oscar '
2  var dict = new Array();
3  var keyValuePair = text.split(' = ');
4  dict[ keyValuePair[0] ] = 'whatever';
5  alert( dict ); // prints nothing.

Fast dort...

  • Zeile 1: Sie sollten einen trimOn-Text so machen, wie er ist name = oscar.
  • Zeile 3: Okay, solange Sie IMMER Leerzeichen um Ihr Gleiches haben. Möglicherweise ist es besser, nicht trimin Zeile 1 =jedes keyValuePair zu verwenden und zu kürzen
  • Fügen Sie nach 3 und vor 4 eine Zeile hinzu:

    key = keyValuePair[0];`
  • Zeile 4: Jetzt wird:

    dict[key] = keyValuePair[1];
  • Zeile 5: Wechseln zu:

    alert( dict['name'] );  // it will print out 'oscar'

Ich versuche zu sagen, dass das dict[keyValuePair[0]]nicht funktioniert. Sie müssen eine Zeichenfolge festlegen keyValuePair[0]und diese als assoziativen Schlüssel verwenden. Nur so habe ich meine zum Arbeiten gebracht. Nachdem Sie es eingerichtet haben, können Sie entweder mit einem numerischen Index darauf verweisen oder Anführungszeichen eingeben.

Hoffentlich hilft das.

Andrea
quelle
4

Alle modernen Browser unterstützen eine Karte , bei der es sich um eine Schlüssel- / Wertdatenbeschränkung handelt. Es gibt mehrere Gründe, die die Verwendung einer Karte besser machen als ein Objekt:

  • Ein Objekt hat einen Prototyp, daher gibt es Standardschlüssel in der Karte.
  • Die Schlüssel eines Objekts sind Zeichenfolgen, wobei sie einen beliebigen Wert für eine Karte haben können.
  • Sie können die Größe einer Karte leicht ermitteln, während Sie die Größe eines Objekts verfolgen müssen.

Beispiel:

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"

Wenn Sie möchten, dass Schlüssel, auf die nicht von anderen Objekten verwiesen wird, als Müll gesammelt werden, sollten Sie eine WeakMap anstelle einer Map verwenden.

Vitalii Fedorenko
quelle
1
var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
// show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}

Dies ist in Ordnung, durchläuft jedoch alle Eigenschaften des Array-Objekts. Wenn Sie nur die Eigenschaften myArray.one, myArray.two ... durchlaufen möchten, versuchen Sie es so

myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
myArray.push("one");
myArray.push("two");
myArray.push("three");
for(i=0;i<maArray.length;i++{
    console.log(myArray[myArray[i]])
}

Jetzt können Sie mit myArray ["one"] auf beide zugreifen und nur über diese Eigenschaften iterieren.

Sasinda Rukshan
quelle
Haben Sie in Ihrem Beispiel die Anzahl der Fehlertypen gezählt? :-) maArray, vergessen geschlossen ')' ...
Brian Haak
Danke für das Beispiel. Wir konnten uns vereinen Arrayund Objectnur mit ObjectBäumen arbeiten! Wunderbare Einsicht! Es ist sehr nützlich zu machen Object.getOwnPropertyNames(obj/array)!
Brian Haak
1
var obj = {};

                for (i = 0; i < data.length; i++) {
                    if(i%2==0) {
                        var left = data[i].substring(data[i].indexOf('.') + 1);
                        var right = data[i + 1].substring(data[i + 1].indexOf('.') + 1);

                        obj[left] = right;
                        count++;
                    }
                }
                console.log("obj");
                console.log(obj);
                // show the values stored
                for (var i in obj) {
                    console.log('key is: ' + i + ', value is: ' + obj[i]);
                }

            }
        };

}}

user2266928
quelle