Wie erstelle ich ein Wörterbuch und füge Schlüssel-Wert-Paare dynamisch hinzu?

323

Von der Post:

Senden eines JSON-Arrays zum Empfang als Dictionary <string, string>

Ich versuche das Gleiche wie dieser Beitrag zu tun. Das einzige Problem ist, dass ich nicht weiß, was die Schlüssel und die Werte im Voraus sind. Ich muss also in der Lage sein, die Schlüssel- und Wertepaare dynamisch hinzuzufügen, und ich weiß nicht, wie das geht.

Weiß jemand, wie man dieses Objekt erstellt und Schlüsselwertpaare dynamisch hinzufügt?

Ich habe es versucht:

var vars = [{key:"key", value:"value"}];
vars[0].key = "newkey";
vars[0].value = "newvalue";

Das geht aber nicht

KenEucker
quelle
2
Es funktioniert großartig. console.log (vars); zeig mir [Objektschlüssel: "newkey" Wert: "newvalue" proto : Object]
Alex Pliutau
Abgesehen davon, dass es sich um eine Liste handelt, nicht um ein Wörterbuch: \ Ich denke, die Daten werden auch besser als Liste von "Paaren" dargestellt list = [["key1","value1"],["key2","value2"]]. Einige andere Sprachen haben den Typ "Paar" oder "Tupel". tldr für das tatsächliche Diktat hinzufügen:dict['key'] = "value"
Jordan Stewart

Antworten:

550
var dict = []; // create an empty array

dict.push({
    key:   "keyName",
    value: "the value"
});
// repeat this last part as needed to add more key/value pairs

Grundsätzlich erstellen Sie ein Objektliteral mit zwei Eigenschaften (aufgerufen keyund value) und fügen es (using push()) in das Array ein.


Bearbeiten: Fast 5 Jahre später erhält diese Antwort negative Stimmen, da kein "normales" JS-Objektliteral erstellt wird (auch bekannt als map, aka hash, aka dictionary).
Es wird jedoch die Struktur erstellt, nach der OP gefragt hat (und die in der anderen verknüpften Frage dargestellt ist), bei der es sich um ein Array von Objektliteralen mit keyund valueEigenschaften handelt. Fragen Sie mich nicht, warum diese Struktur erforderlich war, aber es ist die, nach der gefragt wurde.

Aber, wenn Sie das wollen, was Sie in einem einfachen JS-Objekt wollen - und nicht die Struktur, nach der OP gefragt hat -, lesen Sie die Antwort von tcll , obwohl die Klammernotation etwas umständlich ist, wenn Sie nur einfache Schlüssel haben, die gültige JS-Namen sind. Sie können dies einfach tun:

// object literal with properties
var dict = {
  key1: "value1",
  key2: "value2"
  // etc.
};

Oder verwenden Sie die reguläre Punktnotation, um Eigenschaften nach dem Erstellen eines Objekts festzulegen:

// empty object literal with properties added afterward
var dict = {};
dict.key1 = "value1";
dict.key2 = "value2";
// etc.

Sie tun wollen , die Dirac-Notation , wenn Sie Schlüssel haben , die Leerzeichen in ihnen, Sonderzeichen haben oder solche Sachen. Z.B:

var dict = {};

// this obviously won't work
dict.some invalid key (for multiple reasons) = "value1";

// but this will
dict["some invalid key (for multiple reasons)"] = "value1";

Sie möchten auch eine Klammernotation, wenn Ihre Schlüssel dynamisch sind:

dict[firstName + " " + lastName] = "some value";

Beachten Sie, dass Schlüssel (Eigenschaftsnamen) immer Zeichenfolgen sind und Nicht-Zeichenfolgenwerte bei Verwendung als Schlüssel zu einer Zeichenfolge gezwungen werden. Beispielsweise wird ein DateObjekt in seine Zeichenfolgendarstellung konvertiert:

dict[new Date] = "today's value";

console.log(dict);
// => {
//      "Sat Nov 04 2016 16:15:31 GMT-0700 (PDT)": "today's value"
//    }

Beachten Sie jedoch, dass dies nicht unbedingt "nur funktioniert", da viele Objekte eine Zeichenfolgendarstellung haben, "[object Object]"die keinen nicht eindeutigen Schlüssel ergibt. Seien Sie also vorsichtig bei etwas wie:

var objA = { a: 23 },
    objB = { b: 42 };

dict[objA] = "value for objA";
dict[objB] = "value for objB";

console.log(dict);
// => { "[object Object]": "value for objB" }

Trotz objAund objBvöllig unterschiedliche und einzigartige Elemente sein, sie beide haben die gleiche Grund String - Darstellung: "[object Object]".

Der Grund Datedafür ist, dass der DatePrototyp über eine benutzerdefinierte toStringMethode verfügt, die die Standarddarstellung der Zeichenfolge überschreibt. Und Sie können das Gleiche tun:

// a simple constructor with a toString prototypal method
function Foo() {
  this.myRandomNumber = Math.random() * 1000 | 0;
}

Foo.prototype.toString = function () {
  return "Foo instance #" + this.myRandomNumber;
};

dict[new Foo] = "some value";

console.log(dict);
// => {
//      "Foo instance #712": "some value"
//    }

(Da oben eine Zufallszahl verwendet wird , können Namenskollisionen immer noch sehr leicht auftreten. Dies dient nur zur Veranschaulichung einer Implementierung von toString.)

Wenn Sie also versuchen, Objekte als Schlüssel zu verwenden, verwendet JS toStringgegebenenfalls die eigene Implementierung des Objekts oder die Standard-Zeichenfolgendarstellung.

Flambino
quelle
2
Ist das assoziativ?
Csaba Toth
1
@CsabaToth Nein, dictist kein assoziatives Wörterbuch. Es ist ein Array von Objekten, von denen jedes ein bisschen wie ein Wörterbuch mit zwei Schlüsseln ist: "Schlüssel" und "Wert".
Roman Starkov
1
Was Sie dort haben, ist ein Array, das lediglich den Namen "dict" trägt.
Jan Kyu Peblik
2
Schätzen Sie das Update und verfolgen Sie zusätzliche Informationen.
Jacob
410
var dict = {};

dict['key'] = "testing";

console.log(dict);

funktioniert genauso wie Python :)

Konsolenausgabe:

Object {key: "testing"} 
Tcll
quelle
3
Dies ist sicherlich der beste Ansatz zum Erstellen eines Wörterbuchs und IST die richtige Antwort!
Roman
3
Sehr wichtig, um mit Klammern {}anstatt Klammern zu initialisieren
Jaider
Ich benutze auch grundlegende Objekte als solche Wörterbücher. Schön zu sehen, dass das der richtige Weg ist!
TKoL
5
"Schönheit" von Javascript! Objekt ist tatsächlich ein Schlüsselwertpaar-Wörterbuch selbst
100r
1
@ Azurespot Der Schlüssel kann alles sein, was hashbar ist. Die Schlüssel werden schließlich nach Hash sortiert, was in Python3 bei jedem Lauf anders ist.
Tcll
54

Es ist so einfach wie:

var blah = {}; // make a new dictionary (empty)

oder

var blah = {key: value, key2: value2}; // make a new dictionary with two pairs 

dann

blah.key3 = value3; // add a new key/value pair
blah.key2; // returns value2
blah['key2']; // also returns value2
Simon Sarris
quelle
1
@ KenEucker Ich denke, es ist nützlich, bei Fragen wie diesen falsche Antworten zu haben. Besonders wenn jemand erklärt, warum er falsch liegt, ist dies eine gute Lernressource.
CJBrew
32

Da Sie angegeben haben, dass Sie ein Wörterbuchobjekt möchten (und kein Array, von dem ich annehme, dass einige es verstanden haben), denke ich, dass Sie danach suchen :

var input = [{key:"key1", value:"value1"},{key:"key2", value:"value2"}];

var result = {};

for(var i = 0; i < input.length; i++)
{
    result[input[i].key] = input[i].value;
}

console.log(result); // Just for testing
Zen-Meister
quelle
Die andere Lösung, die .push in einem Array verwendet, funktioniert für meine Zwecke, aber ich gehe davon aus, dass dies auch funktionieren würde, wenn ich es versuchen würde.
KenEucker
2
Wenn ich nicht falsch verstehe, was ein Dictionary-Objekt ist, ist Ihre Frage dann irreführend. Wie würden Sie einen Wert per Schlüssel aus Ihrem Array abrufen?
ZenMaster
Ich verwende JSON.stringify für dieses Objekt und fange es dann mit einem Controller in MVC 3 ab. Dies ist nur so, dass es richtig formatiert ist, bevor es stringifiziert und weitergeleitet wird.
KenEucker
23

JavaScript Object ist an sich wie ein Wörterbuch. Das Rad muss nicht neu erfunden werden.

var dict = {};

// Adding key-value -pairs
dict['key'] = 'value'; // Through indexer
dict.anotherKey = 'anotherValue'; // Through assignment

// Looping through
for (var item in dict) {
  console.log('key:' + item + ' value:' + dict[item]);
  // Output
  // key:key value:value
  // key:anotherKey value:anotherValue
}

// Non existent key
console.log(dict.notExist); // undefined

// Contains key?
if (dict.hasOwnProperty('key')) {
  // Remove item
  delete dict.key;
}

// Looping through
for (var item in dict) {
  console.log('key:' + item + ' value:' + dict[item]);
  // Output
  // key:anotherKey value:anotherValue
}

Geige

Jani Hyytiäinen
quelle
11

Sie können Karten Mapwie folgt verwenden:

var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
Preetham Kumar P.
quelle
9

Ich bin zufällig auf diese Frage gestoßen und habe nach etwas Ähnlichem gesucht. Es gab mir genug Informationen, um einen Test durchzuführen, um die gewünschte Antwort zu erhalten. Wenn also jemand anderes wissen möchte, wie man ein {key: 'value'} -Paar in einem JavaScript-Objekt dynamisch hinzufügt oder nachschlägt, sollte dieser Test Ihnen alles sagen, was Sie möglicherweise wissen müssen.

var dictionary = {initialkey: 'initialValue'};
var key = 'something';
var key2 =  'somethingElse';
var value = 'value1';
var value2 = 'value2';
var keyInitial = 'initialkey';

console.log(dictionary[keyInitial]);

dictionary[key] =value;
dictionary[key2] = value2;
console.log(dictionary);

Ausgabe

initialValue
{ initialkey: 'initialValue',
  something: 'value1',
  somethingElse: 'value2' }
user2301449
quelle
2
Dies ist keine Frage. Sie sollten stattdessen die Frage stellen und sie dann selbst beantworten. Das wäre viel einfacher zu verstehen und zu organisieren.
SalmonKiller
1
danke @SalmonKiller Ich war mir nicht sicher, welche Terminologie ich verwenden sollte, um meine eigene Frage zu schreiben und zu erwarten, dass sie verstanden wird, aber dann habe ich bei meiner Suche darauf gestoßen, dass alle Informationen vorhanden waren, aber auf mehrere Antworten verteilt waren Eine Möglichkeit, die es für jemanden beantworten würde, der auf diese Frage gestoßen ist und nach dem gleichen
Thema
1
LOL. Ich habe das überprüft und es sah aus wie eine Frage statt einer Antwort. Tut mir leid, Mann!
SalmonKiller
Vielen Dank, dass Sie dies hinzugefügt haben. Sie könnten es auch wie die obige Antwort in eine Geige stecken.
KenEucker
8
var dictionary = {};//create new object
dictionary["key1"] = value1;//set key1
var key1 = dictionary["key1"];//get key1
SharpCoder
quelle
Für eine zusätzliche Leistung sollten Sie key1 = dictionary.key1eher referenzieren als indexierenkey1 = dictionary["key1"]
Tcll
4

Sie können ein Klassenwörterbuch erstellen, um problemlos mit der Wörterbuchliste zu interagieren:

class Dictionary {
  constructor() {
    this.items = {};
  }
  has(key) {
    return key in this.items;
  }
  set(key,value) {
    this.items[key] = value;
  }
  delete(key) {
    if( this.has(key) ){
      delete this.items[key]
      return true;
    }
    return false;
  }
}

var d = new Dictionary();
d.set(1, "value1")
d.set(2, "value2")
d.set(3, "value3")
console.log(d.has(2));
d.delete(2);
console.log(d.has(2));

agonza1
quelle
3

Wie wäre es mit dem einen Liner zum Erstellen eines Schlüsselwertpaars?

let result = { ["foo"]: "some value" };

und einige Iteratorfunktionen reducekonvertieren gerne ein Array dynamisch in ein Wörterbuch

var options = [
  { key: "foo", value: 1 },
  { key: "bar", value: {id: 2, name: "two"} },
  { key: "baz", value: {["active"]: true} },
];

var result = options.reduce((accumulator, current) => {
  accumulator[current.key] = current.value;
  return accumulator;
}, {});

console.log(result);

Dan Dohotaru
quelle
3

In modernem Javascript (ES6 / ES2015) sollte die Kartendatenstruktur für das Wörterbuch verwendet werden. In der Map-Datenstruktur in ES6 können Sie beliebige Werte als Schlüssel verwenden.

const map = new Map();
map.set("true", 1);
map.set("false", 0);

Wenn Sie noch ES5 verwenden, besteht die richtige Methode zum Erstellen eines Wörterbuchs darin, ein Objekt ohne Prototyp auf folgende Weise zu erstellen.

var map = Object.create(null);
map["true"]= 1;
map["false"]= 0;

Das Erstellen eines Wörterbuchs ohne Prototypobjekt bietet viele Vorteile. Die folgenden Blogs sind zu diesem Thema lesenswert.

Diktatmuster

Objekte als Karten

Jyoti Prasad Pal
quelle
2

Es würde einer Menge helfen zu wissen, was Ihr gewünschtes Endergebnis ist, aber ich denke, das ist, was Sie wollen:

var vars = [{key:"key", value:"value"}];

vars.push({key: "newkey", value: "newvalue"})
gddc
quelle
2

Ich bin auf dieses Problem gestoßen .. aber innerhalb einer for-Schleife. Die Top-Lösung funktionierte nicht (wenn Variablen (und keine Zeichenfolgen) für die Parameter der Push-Funktion verwendet wurden), und die anderen berücksichtigten keine auf Variablen basierenden Schlüsselwerte. Ich war überrascht, dass dieser Ansatz (der in PHP üblich ist) funktioniert hat.

  // example dict/json                  
  var iterateDict = {'record_identifier': {'content':'Some content','title':'Title of my Record'},
    'record_identifier_2': {'content':'Some  different content','title':'Title of my another Record'} };

  var array = [];

  // key to reduce the 'record' to
  var reduceKey = 'title';

  for(key in iterateDict)
   // ultra-safe variable checking...
   if(iterateDict[key] !== undefined && iterateDict[key][reduceKey] !== undefined)
    // build element to new array key
     array[key]=iterateDict[key][reduceKey];
redcap3000
quelle
1

Eine Verbesserung var dict = {}ist zu verwendenvar dict = Object.create(null) .

Dadurch wird ein leeres Objekt erstellen , die sie nicht haben , Object.prototypewie es den Prototyp.

var dict1 = {};
if (dict1["toString"]){
    console.log("Hey, I didn't put that there!")
}
var dict2 = Object.create(null);
if (dict2["toString"]){
    console.log("This line won't run :)")
}
WoodenKitty
quelle
1

Erstes Array global initialisieren

var dict = []

Objekt zum Wörterbuch hinzufügen

dict.push(
     { key: "One",value: false},
     { key: "Two",value: false},
     { key: "Three",value: false});

Output : 
   [0: {key: "One", value: false}
    1: {key: "Two", value: false}
    2: {key: "Three", value: false}]

Objekt aus dem Wörterbuch aktualisieren

Object.keys(dict).map((index) => {        
  if (index == 1){
    dict[index].value = true
  }
});

Output : 
   [0: {key: "One", value: false},
    1: {key: "Two", value: true},
    2: {key: "Three", value: false}]

Objekt aus dem Wörterbuch löschen

Object.keys(dict).map((index) => {              
      if (index == 2){
        dict.splice(index)
      }
    });

Output : 
    [0: {key: "One", value: false},
     1: {key: "Two", value: true}]
Pratik Panchal
quelle