Come creare un dizionario e aggiungere dinamicamente coppie chiave-valore?


324

Dalla posta:

Invio di un array JSON da ricevere come dizionario <stringa, stringa>

Sto cercando di fare la stessa cosa di quel post. L'unico problema è che non so quali siano le chiavi e i valori in anticipo. Quindi devo essere in grado di aggiungere dinamicamente le coppie chiave e valore e non so come farlo.

Qualcuno sa come creare quell'oggetto e aggiungere dinamicamente coppie di valori-chiave?

Ho provato:

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

Ma questo non funziona.


2
Funziona benissimo. console.log (VAR); show me [Chiave oggetto: "newkey" valore: "newvalue" proto : Object]
Alex Pliutau

Tranne per il fatto che è un elenco, non un dizionario: \ Penso che i dati siano meglio rappresentati anche come un elenco di "coppie" list = [["key1","value1"],["key2","value2"]]. Alcune altre lingue hanno un tipo "coppia" o "tupla". tldr per l'aggiunta effettiva di dict:dict['key'] = "value"
Jordan Stewart

Risposte:


553
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

Fondamentalmente, stai creando un oggetto letterale con 2 proprietà (chiamato keye value) e inserendolo (usando push()) nell'array.


Modifica: Quindi quasi 5 anni dopo, questa risposta sta ricevendo voti negativi perché non sta creando un oggetto JS "normale" letterale (aka mappa, aka hash, aka dizionario).
Si è tuttavia creando la struttura che OP chiesto (e che è illustrata in altra questione legata a), che è una matrice di letterali oggetto , ognuno con keye valueproprietà. Non chiedermi perché era richiesta quella struttura, ma è quella che è stata chiesta.

Ma, tuttavia, se quello che vuoi in un semplice oggetto JS - e non la struttura richiesta da OP - vedi la risposta di tcll , sebbene la notazione tra parentesi sia un po 'ingombrante se hai solo chiavi semplici che sono nomi JS validi. Puoi fare solo questo:

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

Oppure usa la notazione regolare per impostare le proprietà dopo aver creato un oggetto:

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

È cosa vuole la notazione staffa se hai le chiavi che hanno spazi tra loro, caratteri speciali, o cose del genere. Per esempio:

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

Vuoi anche la notazione tra parentesi se le tue chiavi sono dinamiche:

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

Si noti che le chiavi (nomi delle proprietà) sono sempre stringhe e che i valori non stringa verranno convertiti in una stringa quando utilizzati come chiave. Ad esempio un Dateoggetto viene convertito nella sua rappresentazione di stringa:

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

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

Si noti tuttavia che ciò non "funziona", poiché molti oggetti avranno una rappresentazione in forma di stringa "[object Object]"che non costituisce una chiave non univoca. Quindi diffidare di qualcosa come:

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

Nonostante objAe objBessendo elementi completamente diversi e unici, entrambi hanno la stessa rappresentazione di base stringa: "[object Object]".

La ragione per cui Datenon si comporta in questo modo è che il Dateprototipo ha un'abitudinetoString metodo che sovrascrive la rappresentazione di stringa predefinita. E puoi fare lo stesso:

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

(Si noti che poiché quanto sopra utilizza un numero casuale , le collisioni di nomi possono comunque verificarsi molto facilmente. È solo per illustrare un'implementazione di toString.)

Pertanto, quando si tenta di utilizzare gli oggetti come chiavi, JS utilizzerà l' toStringimplementazione dell'oggetto stesso , se presente, o utilizzerà la rappresentazione di stringa predefinita.


2
È associativo?
Csaba Toth,

1
@CsabaToth No, dictnon è un dizionario associativo. È un array di oggetti, ognuno dei quali è un po 'come un dizionario con due chiavi: "chiave" e "valore".
Roman Starkov,

1
Quello che hai lì è un array che si chiama semplicemente 'dict'.
Jan Kyu Peblik,

2
Apprezzo l'aggiornamento e segui ulteriori informazioni.
Jacob,

411
var dict = {};

dict['key'] = "testing";

console.log(dict);

funziona proprio come Python :)

uscita console:

Object {key: "testing"} 

3
Questo è sicuramente l'approccio migliore alla costruzione di un dizionario ed è la risposta corretta!
Romano

3
Molto importante inizializzare con parentesi {}anziché parentesi
Jaider

Uso anche oggetti di base come dizionari come questo. Sono contento di vedere che è il modo giusto!
TKoL

5
'Bellezza' di javascript! L'oggetto è in realtà un dizionario coppia chiave valore stesso
100r

1
@Azurespot la chiave può essere qualsiasi cosa hash, le chiavi sono ordinate da hash dopo tutto, che in python3 differisce ad ogni corsa.
Fino al

53

È semplice come:

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

o

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

poi

blah.key3 = value3; // add a new key/value pair
blah.key2; // returns value2
blah['key2']; // also returns value2

1
@KenEucker Penso che sia utile avere risposte sbagliate in domande come questa. Soprattutto se qualcuno spiega perché hanno torto, è una buona risorsa di apprendimento.
CJBrew,

32

Dal momento che hai affermato che vuoi un oggetto dizionario (e non una matrice come suppongo che alcuni abbiano capito), penso che questo sia ciò che stai cercando:

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

L'altra soluzione che utilizza .push in un array funziona per i miei usi, ma suppongo che funzionerebbe anche se lo provassi.
KenEucker,

2
A meno che non fraintenda cosa sia un oggetto Dizionario, allora la tua domanda è fuorviante. Come recuperare un valore in base alla chiave dall'array?
ZenMaster,

Sto usando JSON.stringify su questo oggetto e poi lo catturo con un controller in MVC 3. Questo è solo per essere formattato correttamente prima di stringerlo e inviarlo.
KenEucker,

23

JavaScript Object è di per sé come un dizionario. Non c'è bisogno di reinventare la ruota.

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
}

Violino


11

Puoi usare le mappe con Map, in questo modo:

var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');

9

Mi è capitato di passare attraverso questa domanda alla ricerca di qualcosa di simile. Mi ha dato informazioni sufficienti per eseguire un test per ottenere la risposta che volevo. Quindi, se qualcun altro vuole sapere come aggiungere o cercare dinamicamente una coppia {chiave: 'valore'} in un oggetto JavaScript, questo test dovrebbe dirti tutto ciò che potresti aver bisogno di sapere.

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);

produzione

initialValue
{ initialkey: 'initialValue',
  something: 'value1',
  somethingElse: 'value2' }

2
Questa non è una domanda. Quello che dovresti fare invece è porre la domanda e quindi rispondere da solo. Sarebbe molto più facile da capire e organizzare.
SalmonKiller il

1
grazie @SalmonKiller non ero sicuro della terminologia corretta per scrivere la mia domanda e mi aspettavo che fosse compresa, ma poi mi sono imbattuto in questo nella mia ricerca tutte le informazioni erano lì ma sparse tra diverse risposte, quindi ho risposto al concetto di questa domanda in un modo che risponderebbe per qualcun altro che si è imbattuto in questa domanda cercando la stessa cosa di me
user2301449

1
LOL. Lo stavo rivedendo e sembrava una domanda invece di una risposta. Scusa!
SalmonKiller il

Grazie per averlo aggiunto. Potresti anche metterlo in un violino come la risposta sopra.
KenEucker,

8
var dictionary = {};//create new object
dictionary["key1"] = value1;//set key1
var key1 = dictionary["key1"];//get key1

per alcune prestazioni aggiuntive, è necessario fare riferimento key1 = dictionary.key1invece che all'indicekey1 = dictionary["key1"]
Tcll

4

È possibile creare un dizionario di classe in modo da poter interagire facilmente con l'elenco dei dizionari:

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));


3

che ne dite dell'unico liner per la creazione di una coppia chiave-valore?

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

e alcune funzioni dell'iteratore gradiscono reduceconvertire dinamicamente un array in un dizionario

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);


3

Nel javascript moderno (ES6 / ES2015), si dovrebbe usare la struttura dei dati della mappa per il dizionario. La struttura dei dati della mappa in ES6 consente di utilizzare valori arbitrari come chiavi.

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

Se stai ancora utilizzando ES5, il modo corretto di creare un dizionario è quello di creare un oggetto senza prototipo nel modo seguente.

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

Ci sono molti vantaggi nella creazione di un dizionario senza un oggetto prototipo. Di seguito vale la pena leggere i blog su questo argomento.

dict-pattern

oggetti-as-mappe


2

Aiuterebbe molto a sapere qual è il risultato finale desiderato, ma penso che questo sia quello che vuoi:

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

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

2

Ho riscontrato questo problema ... ma all'interno di un ciclo for. La soluzione principale non ha funzionato (quando si utilizzano le variabili (e non le stringhe) per i parametri della funzione push), e le altre non hanno tenuto conto dei valori chiave basati sulle variabili. Sono stato sorpreso che questo approccio (che è comune in php) ha funzionato ..

  // 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];

1

Un miglioramento var dict = {}è da usarevar dict = Object.create(null) .

Questo creerà un oggetto vuoto che non ha Object.prototypecome prototipo.

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 :)")
}

1

Prima inizializzazione di array a livello globale

var dict = []

Aggiungi oggetto nel dizionario

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}]

Aggiorna oggetto dal dizionario

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}]

Elimina oggetto dal dizionario

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

Output : 
    [0: {key: "One", value: false},
     1: {key: "Two", value: true}]
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.