Création dynamique de clés dans un tableau associatif JavaScript

199

Comment créer dynamiquement des clés dans des tableaux associatifs javascript?

Toute la documentation que j'ai trouvée jusqu'à présent est de mettre à jour des clés déjà créées:

 arr['key'] = val;

J'ai une chaîne comme ça " name = oscar "

Et je veux finir avec quelque chose comme ça:

{ name: 'whatever' }

Autrement dit, je divise la chaîne et obtenir le premier élément, et je veux mettre cela dans un dictionnaire.

Code

var text = ' name = oscar '
var dict = new Array();
var keyValuePair = text.split(' = ');
dict[ keyValuePair[0] ] = 'whatever';
alert( dict ); // prints nothing.
OscarRyz
la source
24
Lien vers la réponse d' Eugene pour plus de commodité
user56reinstatemonica8

Réponses:

143

Utilisez le premier exemple. Si la clé n'existe pas, elle sera ajoutée.

var a = new Array();
a['name'] = 'oscar';
alert(a['name']);

Affiche une boîte de message contenant «oscar».

Essayer:

var text = 'name = oscar'
var dict = new Array()
var keyValuePair = text.replace(/ /g,'').split('=');
dict[ keyValuePair[0] ] = keyValuePair[1];
alert( dict[keyValuePair[0]] );
tvanfosson
la source
Je l'ai exécuté comme exemple dans Firefox juste pour être sûr. Vous êtes-vous assuré de mettre «nom» entre guillemets?
tvanfosson
1
Euh non, parce que je crée la clé "dynamiquement" et non statiquement. Laissez-moi tout de même vérifier :)
OscarRyz
2
Veuillez vous référer à l'explication plus complète de Danny. Vous ne pourrez pas faire référence aux valeurs du tableau dans une boucle for avec un index (comme myarray [i]). J'espère que ce n'est pas trop déroutant.
MK_Dev
4
Encore mieux est d'utiliser un objet (notation parenthèse {}) pour éviter la surcharge d'avoir .length, .slice (), etc. qui sont inclus dans le prototype Array
bjornl
488

D'une manière ou d'une autre, tous les exemples, bien qu'ils fonctionnent bien, sont trop compliqués:

  • Ils utilisent new Array(), qui est une surpuissance (et une surcharge) pour un tableau associatif simple (dictionnaire AKA).
  • Les meilleurs utilisent new Object(). Fonctionne bien, mais pourquoi toute cette frappe supplémentaire?

Cette question est étiquetée "débutant", alors simplifions les choses.

La manière la plus simple d'utiliser un dictionnaire en JavaScript ou "Pourquoi JavaScript n'a pas d'objet de dictionnaire spécial?":

// create an empty associative array (in JavaScript it is called ... Object)
var dict = {};   // huh? {} is a shortcut for "new Object()"

// add a key named fred with value 42
dict.fred = 42;  // we can do that because "fred" is a constant
                 // and conforms to id rules

// add a key named 2bob2 with value "twins!"
dict["2bob2"] = "twins!";  // we use the subscript notation because
                           // the key is arbitrary (not id)

// add an arbitrary dynamic key with a dynamic value
var key = ..., // insanely complex calculations for the key
    val = ...; // insanely complex calculations for the value
dict[key] = val;

// read value of "fred"
val = dict.fred;

// read value of 2bob2
val = dict["2bob2"];

// read value of our cool secret key
val = dict[key];

Modifions maintenant les valeurs:

// change the value of fred
dict.fred = "astra";
// the assignment creates and/or replaces key-value pairs

// change value of 2bob2
dict["2bob2"] = [1, 2, 3];  // any legal value can be used

// change value of our secret key
dict[key] = undefined;
// contrary to popular beliefs assigning "undefined" does not remove the key

// go over all keys and values in our dictionary
for (key in dict) {
  // for-in loop goes over all properties including inherited properties
  // let's use only our own properties
  if (dict.hasOwnProperty(key)) {
    console.log("key = " + key + ", value = " + dict[key]);
  }
}

La suppression de valeurs est également très simple:

// let's delete fred
delete dict.fred;
// fred is removed, the rest is still intact

// let's delete 2bob2
delete dict["2bob2"];

// let's delete our secret key
delete dict[key];

// now dict is empty

// let's replace it, recreating all original data
dict = {
  fred:    42,
  "2bob2": "twins!"
  // we can't add the original secret key because it was dynamic,
  // we can only add static keys
  // ...
  // oh well
  temp1:   val
};
// let's rename temp1 into our secret key:
if (key != "temp1") {
  dict[key] = dict.temp1; // copy the value
  delete dict.temp1;      // kill the old key
} else {
  // do nothing, we are good ;-)
}
Eugene Lazutkin
la source
2
Bonjour, je sais que je réponds à l'ancienne réponse, mais elle occupe une place de choix sur Google, je vais donc demander quand même. Je suis un peu confus sur ce que "nous ne pouvons pas ajouter la clé secrète d'origine car elle était dynamique, nous ne pouvons ajouter que des clés statiques" signifie dans votre exemple.
Karel Bílek
1
Cela signifie précisément ce qu'il dit: nous ne connaissons pas sa valeur, nous ne pouvons donc pas le représenter comme une constante, ce qui est requis lors de la spécification d'une clé dans un objet littéral.
Eugene Lazutkin
3
Cependant, "nous ne pouvons pas ajouter la clé secrète d'origine car elle était dynamique" n'est pas correct en soi, même si vous ne pouvez pas utiliser une variable comme clé directement dans {}, ou comme clé avec notation par points. Nous pouvons toujours ajouter une clé dynamique via "dict [key] = val", comme vous le montrez au début de l'exemple. La limitation réside dans l'utilisation de la note {}, plutôt que dans la clé elle-même.
Zut
8
Cela ressemble à la réponse de Sheldon Cooper :)
jpatiaga
4
réponse complète parfaite, devrait être la valeur par défaut
Dennis Golomazov
29

Javascript n'a pas de tableaux associatifs , il a des objets .

Les lignes de code suivantes font toutes exactement la même chose - définissez le champ «nom» d'un objet sur «orion».

var f = new Object(); f.name = 'orion';
var f = new Object(); f['name'] = 'orion';
var f = new Array(); f.name = 'orion';
var f = new Array(); f['name'] = 'orion';
var f = new XMLHttpRequest(); f['name'] = 'orion';

Il semble que vous ayez un tableau associatif car an Arrayest également unObject - mais vous n'ajoutez pas du tout de choses dans le tableau, vous définissez des champs sur l'objet.

Maintenant que cela est clarifié, voici une solution de travail à votre exemple

var text = '{ name = oscar }'
var dict = new Object();

// Remove {} and spaces
var cleaned = text.replace(/[{} ]/g, '');

// split into key and value
var kvp = cleaned.split('=');

// put in the object
dict[ kvp[0] ] = kvp[1];
alert( dict.name ); // prints oscar.
Orion Edwards
la source
En supposant que la chaîne de texte a effectivement les accolades, vous pouvez plus ou moins la traiter comme JSON .. remplacez le signe = par un: et vous avez un objet à
évaluer
1
Oups, la chaîne n'est pas délimitée correctement. Rien d'exceptionnel ne peut réparer.
neonski
9

En réponse à MK_Dev, on est capable d'itérer, mais pas consécutivement. (Pour cela, un tableau est évidemment nécessaire)

La recherche rapide sur Google fait apparaître des tables de hachage en javascript

Exemple de code pour boucler les valeurs dans un hachage (à partir du lien susmentionné):

var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;

// show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}
Danny
la source
5

Code d'origine (j'ai ajouté les numéros de ligne pour pouvoir y faire référence):

1  var text = ' name = oscar '
2  var dict = new Array();
3  var keyValuePair = text.split(' = ');
4  dict[ keyValuePair[0] ] = 'whatever';
5  alert( dict ); // prints nothing.

Presque là...

  • ligne 1: vous devez faire un trimtexte sur tel quel name = oscar.
  • ligne 3: d'accord tant que vous avez TOUJOURS des espaces autour de votre égal. peut-être mieux de ne pas être trimdans la ligne 1, utilisez =et coupez chaque paire KeyValuePair
  • ajouter une ligne après 3 et avant 4:

    key = keyValuePair[0];`
  • ligne 4: devient maintenant:

    dict[key] = keyValuePair[1];
  • ligne 5: remplacer par:

    alert( dict['name'] );  // it will print out 'oscar'

Ce que j'essaie de dire, c'est que le dict[keyValuePair[0]]ne fonctionne pas, vous devez définir une chaîne keyValuePair[0]et l'utiliser comme clé associative. C'est la seule façon dont j'ai fait travailler la mienne. Après l'avoir configuré, vous pouvez vous y référer avec un index numérique ou saisir des guillemets.

J'espère que cela pourra aider.

Andrea
la source
4

Tous les navigateurs modernes prennent en charge une carte , qui est une restriction de données clé / valeur. Il y a quelques raisons qui rendent l'utilisation d'une carte meilleure que l'objet:

  • Un objet a un prototype, il y a donc des clés par défaut dans la carte.
  • Les clés d'un objet sont des chaînes, où elles peuvent être n'importe quelle valeur pour une carte.
  • Vous pouvez facilement obtenir la taille d'une carte tout en gardant une trace de la taille d'un objet.

Exemple:

var myMap = new Map();

var keyObj = {},
    keyFunc = function () {},
    keyString = "a string";

myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

myMap.size; // 3

myMap.get(keyString);    // "value associated with 'a string'"
myMap.get(keyObj);       // "value associated with keyObj"
myMap.get(keyFunc);      // "value associated with keyFunc"

Si vous souhaitez que les clés qui ne sont pas référencées à partir d'autres objets soient récupérées, pensez à utiliser un WeakMap au lieu d'une carte.

Vitalii Fedorenko
la source
1
var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
// show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}

c'est ok mais itère à travers chaque propriété de l'objet tableau. si vous voulez seulement parcourir les propriétés myArray.one, myArray.two ... vous essayez comme ça

myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
myArray.push("one");
myArray.push("two");
myArray.push("three");
for(i=0;i<maArray.length;i++{
    console.log(myArray[myArray[i]])
}

vous pouvez désormais accéder à la fois par myArray ["one"] et itérer uniquement via ces propriétés.

Sasinda Rukshan
la source
Avez-vous compté le nombre de fautes de frappe dans votre exemple? :-) maArray, oublié fermé ')' ...
Brian Haak
Merci pour l'exemple. Nous pourrions nous unir Arrayet Objecttravailler uniquement avec des Objectarbres! Un aperçu merveilleux! C'est très utile à faire Object.getOwnPropertyNames(obj/array)!
Brian Haak
1
var obj = {};

                for (i = 0; i < data.length; i++) {
                    if(i%2==0) {
                        var left = data[i].substring(data[i].indexOf('.') + 1);
                        var right = data[i + 1].substring(data[i + 1].indexOf('.') + 1);

                        obj[left] = right;
                        count++;
                    }
                }
                console.log("obj");
                console.log(obj);
                // show the values stored
                for (var i in obj) {
                    console.log('key is: ' + i + ', value is: ' + obj[i]);
                }

            }
        };

}

user2266928
la source