Comment créer un dictionnaire et ajouter dynamiquement des paires clé-valeur?

324

De la poste:

Envoi d'un tableau JSON à recevoir en tant que 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. J'ai donc besoin de pouvoir ajouter dynamiquement les paires clé / valeur et je ne sais pas comment faire.

Quelqu'un sait-il comment créer cet objet et ajouter dynamiquement des paires valeur / clé?

J'ai essayé:

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

Mais ça ne marche pas.

KenEucker
la source
2
Cela fonctionne très bien. console.log (vars); montrez-moi [Object key: "newkey" value: "newvalue" proto : Object]
Alex Pliutau
Sauf que c'est une liste, pas un dictionnaire: \ Je pense que les données sont également mieux représentées comme une liste de "paires" list = [["key1","value1"],["key2","value2"]]. Certaines autres langues ont un type "paire" ou "tuple". tldr pour dict réel ajoutant:dict['key'] = "value"
Jordan Stewart

Réponses:

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

Fondamentalement, vous créez un littéral d'objet avec 2 propriétés (appelées keyet value) et vous l'insérez (en utilisant push()) dans le tableau.


Edit: Donc, près de 5 ans plus tard, cette réponse obtient des votes négatifs car elle ne crée pas un littéral d'objet JS "normal" (alias carte, alias hachage, alias dictionnaire).
Il est cependant de créer la structure qui a demandé OP (et qui est illustrée dans l'autre question liée à), qui est un tableau de littéraux d'objets , chacun avec keyet valuepropriétés. 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 objet JS simple - et non la structure demandée par OP - voir la réponse de tcll , bien que la notation entre crochets soit un peu lourde si vous n'avez que 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 régulière pour définir les propriétés après avoir créé un objet:

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

Vous ne voulez que la notation de support si vous avez des clés qui ont des espaces en eux, des caractères spéciaux, ou des choses comme ça. 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 la notation des parenthèses si vos clés sont dynamiques:

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

Notez que les clés (noms de propriété) sont toujours des chaînes et que les valeurs non-chaîne seront contraintes à une chaîne lorsqu'elles seront utilisées comme clé. Par exemple, un Dateobjet 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 "simplement", car de nombreux objets auront une représentation sous forme de chaîne comme celle "[object Object]"qui ne donne pas une clé non unique. Méfiez-vous donc 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" }

En dépit objAet objBétant 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 Datene se comporte pas comme ceci est que le Dateprototype a une toStringméthode personnalisée qui remplace la représentation de chaîne par défaut. Et vous pouvez faire de même:

// 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 comme ce qui précède utilise un nombre aléatoire , les collisions de noms peuvent toujours se produire très facilement. C'est juste pour illustrer une implémentation detoString .)

Ainsi, lorsque vous essayez d'utiliser des objets comme clés, JS utilise la propre toStringimplémentation de l'objet , le cas échéant, ou utilise la représentation de chaîne par défaut.

Flambino
la source
2
Est-ce associatif?
Csaba Toth du
1
@CsabaToth Non, dictn'est pas un dictionnaire associatif. C'est un tableau d'objets, chacun étant un peu comme un dictionnaire avec deux clés: "clé" et "valeur".
Roman Starkov
1
Ce que vous avez là est un tableau qui est simplement nommé «dict».
Jan Kyu Peblik
2
Appréciez la mise à jour et suivez les informations supplémentaires.
Jacob
411
var dict = {};

dict['key'] = "testing";

console.log(dict);

fonctionne comme python :)

sortie console:

Object {key: "testing"} 
Tcll
la source
3
C'est certainement la meilleure approche pour construire un dictionnaire, et c'est la bonne réponse!
Roman
3
Très important d'initialiser avec des crochets {}plutôt qu'avec des parenthèses
Jaider
J'utilise également des objets de base comme des dictionnaires comme celui-ci. Heureux de voir que c'est la bonne façon!
TKoL
5
«Beauté» de javascript! L'objet EST réellement un dictionnaire de paires de valeurs clés lui
100r
1
@Azurespot, la clé peut être tout ce qui est lavable, les clés sont ordonnées par hachage après tout, ce qui en python3 diffère à chaque exécution.
Tcll
53

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 

puis

blah.key3 = value3; // add a new key/value pair
blah.key2; // returns value2
blah['key2']; // also returns value2
Simon Sarris
la source
1
@KenEucker Je pense qu'il est utile d'avoir de mauvaises réponses dans des questions comme celle-ci. Surtout si quelqu'un explique pourquoi ils ont tort, c'est une bonne ressource d'apprentissage.
CJBrew
32

Puisque vous avez déclaré que vous vouliez un objet dictionnaire (et non un tableau comme je suppose que certains l'ont 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
ZenMaster
la source
L'autre solution utilisant .push dans un tableau fonctionne pour mes utilisations, mais je suppose que cela fonctionnerait également si je l'essayais.
KenEucker
2
À moins que je ne comprenne mal ce qu'est un objet Dictionary, votre question est alors trompeuse. Comment récupéreriez-vous une valeur par clé de votre tableau?
ZenMaster
J'utilise JSON.stringify sur cet objet, puis je l'attrape avec un contrôleur dans MVC 3. C'est juste pour qu'il soit correctement formaté avant de le stringifier et de l'envoyer.
KenEucker
23

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

Jani Hyytiäinen
la source
11

Vous pouvez utiliser des cartes avec Map, comme ceci:

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

Je suis tombé sur cette question à la recherche de quelque chose de similaire. Cela m'a donné suffisamment d'informations pour effectuer 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 {key: 'value'} dans un objet JavaScript, ce test devrait vous dire tout ce que vous pourriez avoir besoin de 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);

production

initialValue
{ initialkey: 'initialValue',
  something: 'value1',
  somethingElse: 'value2' }
user2301449
la source
2
Ce n'est pas une question. Ce que vous devez faire à la place, c'est poser la question puis y répondre vous-même. Ce serait beaucoup plus facile à comprendre et à organiser.
SalmonKiller
1
merci @SalmonKiller je n'étais pas sûr de la bonne terminologie pour écrire ma propre question et je m'attendais à ce qu'elle soit comprise mais ensuite je suis tombé sur ceci dans ma recherche toutes les informations étaient là mais réparties entre plusieurs réponses donc j'ai répondu au concept de cette question dans un façon qui pourrait y répondre pour quelqu'un d'autre qui est tombé sur cette question à la recherche de la même chose que moi
user2301449
1
LOL. J'examinais cela et cela ressemblait à une question plutôt qu'à une réponse. Désolé mec!
SalmonKiller
Merci d'avoir ajouté ceci. Vous pouvez également le mettre dans un violon comme la réponse ci-dessus.
KenEucker
8
var dictionary = {};//create new object
dictionary["key1"] = value1;//set key1
var key1 = dictionary["key1"];//get key1
SharpCoder
la source
pour des performances supplémentaires, vous devriez référencer key1 = dictionary.key1plutôt qu'indexerkey1 = dictionary["key1"]
Tcll
4

Vous pouvez créer un dictionnaire de classe pour 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));

agonza1
la source
3

que diriez-vous du liner pour créer une paire de valeurs clés?

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

et une fonction d'itérateur comme reduceconvertir 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);

Dan Dohotaru
la source
3

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

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

Si vous utilisez toujours ES5, la façon 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;

Il existe de nombreux avantages à créer un dictionnaire sans objet prototype. Les blogs ci-dessous méritent d'être lus sur ce sujet.

dict-pattern

objets en tant que cartes

Jyoti Prasad Pal
la source
2

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

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

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

J'ai rencontré ce problème .. mais dans une boucle for. La solution supérieure 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 ne tenaient pas compte des valeurs clés 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];
redcap3000
la source
1

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

Cela va créer un objet vide qui ne pas avoir Object.prototypecomme prototype de lui.

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
la source
1

Première initialisation d'un tableau à l'échelle mondiale

var dict = []

Ajouter un objet dans le dictionnaire

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

Mettre à jour l'objet à partir du dictionnaire

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

Supprimer un objet du dictionnaire

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

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