web-dev-qa-db-fra.com

Comment créer un dictionnaire et ajouter des paires clé-valeur de manière dynamique?

De poste:

Envoi d'un tableau JSON à recevoir sous forme de dictionnaire <chaîne, chaîne>

J'essaie de faire la même chose que ce post. Le seul problème est que je ne sais pas quelles sont les clés et les valeurs initiales. Je dois donc pouvoir ajouter dynamiquement les paires clé/valeur et je ne sais pas comment le faire.

Est-ce que quelqu'un sait comment créer cet objet et ajouter des paires clé-valeur de manière dynamique?

J'ai essayé:

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

Mais ça ne marche pas.

270
KenEucker
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

Fondamentalement, vous créez un littéral d'objet avec 2 propriétés (appelées key et value) et l'insérez (à l'aide de Push()) dans le tableau.


Edit: Donc, presque 5 ans plus tard, cette réponse reçoit des votes négatifs car elle ne crée pas d'objet littéral "normal" JS (aka map, aka hash, aka dictionnaire).
Il est mais crée la structure demandée par OP (et qui est illustrée dans l’autre question liée à), qui est un tableau de littéraux d'objet , chacun avec les propriétés key et value. Ne me demandez pas pourquoi cette structure était nécessaire, mais c'est celle qui a été demandée.

Mais, mais, si ce que vous voulez dans un simple objet JS - et pas , la structure OP demandée - voir réponse de tcll , bien que la notation entre crochets soit un peu fastidieux si vous avez juste des clés simples qui sont des noms JS valides. Vous pouvez simplement faire ceci:

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

Ou utilisez la notation par points standard pour définir les propriétés après la création d'un objet:

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

Vous faites voulez la notation entre crochets si vous avez des clés comportant des espaces, des caractères spéciaux ou des choses du même genre. Par exemple:

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

Vous souhaitez également une notation entre crochets si vos clés sont dynamiques:

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

Notez que les clés (noms de propriétés) sont toujours des chaînes et que des valeurs autres que des chaînes sont forcées sous forme de chaîne lorsqu'elles sont utilisées comme clé. Par exemple. un objet Date est converti en sa représentation sous forme de chaîne:

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

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

Notez cependant que cela ne "fonctionne pas nécessairement", car de nombreux objets auront une représentation sous forme de chaîne telle que "[object Object]" qui ne crée pas une clé non unique. Alors méfiez-vous de quelque chose comme:

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

Bien que objA et objB soient des éléments complètement différents et uniques, ils ont tous deux la même représentation de chaîne de base: "[object Object]".

La raison pour laquelle Date ne se comporte pas comme ceci est que le prototype Date a une méthode personnalisée toString qui remplace la représentation de chaîne par défaut. Et vous pouvez faire la même chose:

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

(Notez que, puisque ce qui précède utilise un nombre aléatoire , les collisions de noms peuvent encore se produire très facilement. C’est juste pour illustrer une implémentation de toString.)

Ainsi, lorsque vous essayez d'utiliser des objets en tant que clés, JS utilisera l'implémentation toString de l'objet, le cas échéant, ou la représentation sous forme de chaîne par défaut.

472
Flambino
var dict = {};

dict['key'] = "testing";

console.log(dict);

fonctionne exactement comme python :)

sortie de la console:

Object {key: "testing"} 
373
Tcll

C'est aussi simple que:

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

ou

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

ensuite

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

Puisque vous avez dit que vous voulez un objet dictionnaire (et pas un tablea comme je suppose que certains sont compris), je pense que c'est ce que vous recherchez:

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
32
ZenMaster

JavaScript Object est en soi comme un dictionnaire. Pas besoin de réinventer la roue.

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
}

violon

22
Jani Hyytiäinen

Vous pouvez utiliser des cartes avec Map , comme ceci:

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

Il m'est arrivé de traverser cette question à la recherche de quelque chose de similaire. Cela m'a donné assez d’informations pour faire un test afin d’obtenir la réponse que je voulais. Donc, si quelqu'un d'autre veut savoir comment ajouter ou rechercher dynamiquement une paire {clé: 'valeur'} dans un objet JavaScript, ce test devrait vous indiquer tout ce que vous devez éventuellement savoir.

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

sortie

initialValue
{ initialkey: 'initialValue',
  something: 'value1',
  somethingElse: 'value2' }
9
user2301449
var dictionary = {};//create new object
dictionary["key1"] = value1;//set key1
var key1 = dictionary["key1"];//get key1
8
SharpCoder

Vous pouvez créer un dictionnaire de classe afin de pouvoir interagir facilement avec la liste des dictionnaires:

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

J'ai rencontré ce problème .. mais dans une boucle for. La solution principale ne fonctionnait pas (lors de l'utilisation de variables (et non de chaînes) pour les paramètres de la fonction Push) et les autres solutions ne tenaient pas compte des valeurs de clé basées sur des variables. J'ai été surpris que cette approche (qui est courante en php) fonctionne.

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

Cela aiderait beaucoup de savoir quel est votre résultat final recherché, mais je pense que c'est ce que vous voulez:

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

vars.Push({key: "newkey", value: "newvalue"})
2
g.d.d.c

Dans le javascript moderne (ES6/ES2015), il convient d'utiliser la structure de données Map pour le dictionnaire. La structure de données de la carte dans ES6 vous permet d'utiliser des valeurs arbitraires en tant que clés.

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

Si vous utilisez encore ES5, la manière correcte de créer un dictionnaire consiste à créer un objet sans prototype de la manière suivante.

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

La création d'un dictionnaire sans objet prototype présente de nombreux avantages. Les blogs ci-dessous méritent d'être lus sur ce sujet.

dict-pattern

objets-comme-cartes

2
Jyoti Prasad Pal

que diriez-vous de la ligne unique pour créer une paire clé-valeur?

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

et certains itérateurs fonctionnent comme reduce pour convertir dynamiquement un tableau en dictionnaire

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);
2
Dan Dohotaru

Une amélioration sur var dict = {} consiste à utiliser var dict = Object.create(null).

Cela va créer un objet vide qui ne ne pas avoir Object.prototype comme prototype.

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
WoodenKitty