¿Cómo crear diccionario y agregar pares clave–valor dinámicamente?


De post:

Enviar un array JSON para ser recibido como un diccionario

Estoy tratando de hacer lo mismo que ese post. El único problema es que no se cuáles son las claves y los valores por adelantado. Así que necesito ser capaz de añadir dinámicamente los pares clave y valor y no sé cómo hacer eso.

¿Alguien sabe cómo crear ese objeto y agregar pares de valores clave dinámicamente?

He intentado:

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

Pero eso no trabajo.

Author: Xufox, 2011-08-25

13 answers

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

Básicamente, estás creando un objeto literal con 2 propiedades (llamadas key y value) e insertándolo (usando push()) en la matriz.


Edit: Así que casi 5 años después, esta respuesta está recibiendo votos negativos porque no está creando un literal de objeto JS "normal" (también conocido como mapa, también conocido como hash, también conocido como diccionario).
It es sin embargo, creando la estructura que OP pidió (y que se ilustra en la otra pregunta vinculada a), que es un array de objetos literales , cada uno con propiedades key y value. No me preguntes por qué se requería esa estructura, pero es la que se pidió.

Pero, pero, si lo que usted desea en una llanura JS objeto - y no la estructura OP pidió - ver tcll la respuesta de, aunque la notación de corchetes es un poco engorroso si usted acaba de tener una simple llave que son válidos JS nombres. Puedes hacer esto:

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

O use la notación de puntos regular para establecer propiedades después de crear un objeto:

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

quieres la notación entre corchetes si tienes claves que tienen espacios, caracteres especiales o cosas por el estilo. Por ejemplo:

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

También desea la notación entre corchetes si sus claves son dinámicas:

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

Tenga en cuenta que las claves (nombres de propiedad) son siempre cadenas, y los valores que no sean cadenas se coaccionarán a una cadena cuando se usen como clave. Por ejemplo, un objeto Date se convierte a su representación de cadena:

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

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

Tenga en cuenta, sin embargo, que este no necesariamente "solo funciona", ya que muchos objetos tendrán una representación de cadena como "[object Object]" que no hace una clave no única. Así que ten cuidado con algo como:

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

A pesar de que objA y objB son elementos completamente diferentes y únicos, ambos tienen la misma representación de cadena básica: "[object Object]".

La razón por la que Date no se comporta así es que el prototipo Date tiene un método personalizado toString que anula la representación de cadena predeterminada. Y puedes hacer lo mismo:

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

(Tenga en cuenta que dado que el anterior utiliza un número aleatorio, las colisiones de nombres todavía pueden ocurrir muy fácilmente. Es solo para ilustrar una implementación de toString.)

Así que al intentar usar objetos como claves, JS usará la propia implementación toString del objeto, si la hay, o usará la representación de cadena predeterminada.

 373
Author: Flambino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:26
var dict = {};

dict['key'] = "testing";

console.log(dict);

Funciona igual que python:)

Salida de consola:

Object {key: "testing"} 
 313
Author: Tcll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-22 08:04:10

Es tan simple como:

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

O

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

Entonces

blah.key3 = value3; // add a new key/value pair
blah.key2; // returns value2
blah['key2']; // also returns value2
 50
Author: Simon Sarris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-25 19:54:04

Ya que has declarado que quieres un objeto de diccionario (y no una matriz como supongo que algunos entendieron) creo que esto es lo que buscas:

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
 31
Author: ZenMaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-25 20:04:57

JavaScript Object es en sí mismo como un diccionario. No hay necesidad de reinventar la rueda.

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
}

Fiddle

 16
Author: Jani Hyytiäinen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-19 15:44:44

Me pasó a caminar a través de esta pregunta en busca de algo similar. Me dio suficiente información para hacer una prueba y obtener la respuesta que quería. Entonces, si alguien más quiere saber cómo agregar o buscar dinámicamente un par {key:' value'} en un objeto JavaScript, esta prueba debería decirle todo lo que necesita saber.

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

Salida

initialValue
{ initialkey: 'initialValue',
  something: 'value1',
  somethingElse: 'value2' }
 8
Author: user2301449,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-02 02:11:18
var dictionary = {};//create new object
dictionary["key1"] = value1;//set key1
var key1 = dictionary["key1"];//get key1
 6
Author: SharpCoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-02 13:35:12

Puede utilizar mapas con Map, así:

var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
 4
Author: Preetham Kumar P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-07 02:35:11

Puede crear un diccionario de clase para que pueda interactuar fácilmente con la lista de diccionarios:

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));
 2
Author: agonza1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-04 14:23:08

Me encontré con este problema.. pero dentro de un bucle for. La solución top no funcionó (al usar variables (y no cadenas) para los parámetros de la función push), y las demás no tuvieron en cuenta los valores clave basados en variables. Me sorprendió que este enfoque (que es común en php) funcionara..

  // 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
Author: redcap3000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-24 22:13:57

¿Qué tal el único liner para crear un par de valores clave?

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

Y algunos iteradores funcionan como reduce para convertir dinámicamente una matriz en un diccionario

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);
 1
Author: Dan Dohotaru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-16 23:26:46

Ayudaría mucho saber cuál es tu resultado final deseado, pero creo que esto es lo que quieres:

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

vars.push({key: "newkey", value: "newvalue"})
 0
Author: g.d.d.c,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-25 19:46:43

Una mejora sobre var dict = {} es usar var dict = Object.create(null).

Esto creará un objeto vacío que no tiene Object.prototype como 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 :)")
}
 0
Author: WoodenKitty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-20 07:53:57