Utilisation d'un entier comme clé dans un tableau associatif en JavaScript


102

Lorsque je crée un nouveau tableau JavaScript et que j'utilise un entier comme clé, chaque élément de ce tableau jusqu'à l'entier est créé comme non défini.

Par exemple:

var test = new Array();
test[2300] = 'Some string';
console.log(test);

affichera 2298 indéfinis et un 'Some string'.

Comment dois-je faire en sorte que JavaScript utilise 2300 comme chaîne au lieu d'un entier, ou comment dois-je l'empêcher d'instancier 2299 indices vides?

Réponses:


128

Utilisez un objet, comme le disent les gens. Cependant, notez que vous ne pouvez pas avoir de clés entières. JavaScript convertira l'entier en chaîne . Les sorties 20 suivantes, non indéfinies:

var test = {}
test[2300] = 20;
console.log(test["2300"]);

12
+1 Notez que c'est même vrai pour les tableaux! voir stackoverflow.com/questions/1450957/…
bobince

1
@bobince: En interne, bien sûr. Cependant, logiquement , les tableaux ont des «clés» entières.
Courses de légèreté en orbite

1
Veuillez noter que l'utilisation d'un entier comme clé changera la longueur de votre tableau. Vous devriez certainement utiliser Object à la place. Je voulais juste utiliser l'identifiant facebook comme clé, et JSON.stringify planterait ma machine;)
Krystian

2
@LightnessRacesinOrbit Les détails internes peuvent toujours s'échapper et vous mordre. Voir cette version simplifiée de ce que j'ai rencontré aujourd'hui: jsfiddle.net/cincodenada/pseujLex/2 Cela peut sembler artificiel une fois réduit, mais faisait partie intégrante d'un script plus large (et est un peu moins artificiel dans CoffeeScript: jsfiddle.net/ cincodenada / oojr7Ltn / 2 ). Ce détail apparent d'implémentation m'a coûté un peu de chasse aux bogues aujourd'hui.
cincodenada

1
Une petite note pour les nombres non entiers: 0.25et .25résolvez la même chaîne "0.25". Donc , si vous utilisez les touches fractionnaires, vous pouvez récupérer la propriété d'une clé numérique mis à l' 0.25aide 0.25, .25, "0.25"mais pas ".25".
Sandy Gifford

34

Vous pouvez simplement utiliser un objet:

var test = {}
test[2300] = 'Some string';

16
Est toujours jeté à la corde.
tirage010 le

1
@ drew010 oui, les objets Javascript permettent l'indexation avec des chaînes uniquement.
Pithikos

22

Comme les gens le disent, JavaScript convertira une chaîne de nombre en entier, il n'est donc pas possible de l'utiliser directement sur un tableau associatif, mais les objets fonctionneront pour vous de la même manière que je pense.

Vous pouvez créer votre objet:

var object = {};

Et ajoutez les valeurs au fur et à mesure que le tableau fonctionne:

object[1] = value;
object[2] = value;

Cela vous donnera:

{
  '1': value,
  '2': value
}

Après cela, vous pouvez y accéder comme un tableau dans d'autres langues pour obtenir la clé:

for(key in object)
{
   value = object[key] ;
}

J'ai testé et fonctionne.


17

Si le cas d'utilisation stocke des données dans une collection, ECMAScript 6 fournit le Maptype.

C'est seulement plus lourd à initialiser.

Voici un exemple:

const map = new Map();
map.set(1, "One");
map.set(2, "Two");
map.set(3, "Three");

console.log("=== With Map ===");

for (const [key, value] of map) {
    console.log(`${key}: ${value} (${typeof(key)})`);
}

console.log("=== With Object ===");

const fakeMap = {
    1: "One",
    2: "Two",
    3: "Three"
};

for (const key in fakeMap) {
    console.log(`${key}: ${fakeMap[key]} (${typeof(key)})`);
}

Résultat:

=== With Map ===
1: One (number)
2: Two (number)
3: Three (number)
=== With Object ===
1: One (string)
2: Two (string)
3: Three (string)

11

Compiler d'autres réponses:

Objet

var test = {};

Lorsque vous utilisez un nombre comme clé de nouvelle propriété, le nombre se transforme en chaîne:

test[2300] = 'Some string';
console.log(test['2300']);
// Output: 'Some string'

Lors de l'accès à la valeur de la propriété en utilisant le même nombre, le nombre est à nouveau transformé en chaîne:

console.log(test[2300]);
// Output: 'Some string'

Lorsque vous récupérez les clés de l'objet, cependant, elles ne seront pas transformées en nombres:

for (var key in test) {
    console.log(typeof key);
}
// Output: 'string'

Carte

ECMAScript 6 permet l'utilisation de l'objet Map ( documentation , comparaison avec Object ). Si votre code est destiné à être interprété localement ou si la table de compatibilité ECMAScript 6 semble suffisamment verte pour vos besoins, envisagez d'utiliser une carte:

var test = new Map();
test.set(2300, 'Some string');
console.log(test.get(2300));
// Output: 'Some string'

Aucune conversion de type n'est effectuée, pour le meilleur et pour le pire:

console.log(test.get('2300'));
// Output: undefined
test.set('2300', 'Very different string');
console.log(test.get(2300));
// Output: 'Some string'

4

Utilisez un objet au lieu d'un tableau. Les tableaux en JavaScript ne sont pas des tableaux associatifs. Ce sont des objets avec de la magie associés à toutes les propriétés dont les noms ressemblent à des entiers. Cette magie n'est pas ce que vous voulez si vous ne les utilisez pas comme une structure traditionnelle de type tableau.

var test = {};
test[2300] = 'some string';
console.log(test);

1
Il peut s'agir de tableaux associatifs, mais uniquement parce qu'il s'agit également d'objets qui peuvent avoir des propriétés nommées. Mais cela rend les choses ridiculement déroutantes, et donc oui, les objets sont bien meilleurs à utiliser.
Graza le

Les tableaux ne peuvent jamais être associatifs Graza. Si vous essayez d'utiliser des clés dans un tableau, puis de les parcourir, vous remarquerez que vous parcourez également toutes les méthodes et propriétés par défaut des tableaux -> pas très souhaitable.
Swizec Teller

@Swizec - exactement pourquoi j'ai dit "ridiculement déroutant". Vous pouvez utiliser un tableau comme un tableau associatif - c'est-à-dire comme des paires nom / valeur, mais vous ne voudriez jamais les itérer! (Je signalais simplement une technicité, ce n'est certainement pas quelque chose que je recommanderais de faire)
Graza

oui, mais lors de l'itération, ils ne sont pas dans un ordre particulier (c'est-à-dire que l'ordre n'est pas garanti), ce qui serait le point de les numéroter, donc c'est bien pire que de simplement dérouter.
Julix

3

Essayez d'utiliser un objet, pas un tableau:

var test = new Object(); test[2300] = 'Some string';

3
C'est certainement la voie à suivre. De cette façon, vous ne créerez pas de tableau long de 2300 entrées pour stocker une seule chaîne.
Krystian

2
Les tableaux @Krystian JS sont de faux tableaux. Exécutez var a = []; a[Math.pow(2, 30)] = 'hello';et vous ne verrez pas l'utilisation du navigateur / de la mémoire augmenter de plus d'un gigaoctet, mais vous verrez que a.lengthc'est 1073741824. Les VM stockent clairement certains «tableaux» en utilisant une autre structure de données, je suppose simplement une table de hachage, du moins si ils sont suffisamment clairsemés.
Andy

2

Obtenez la valeur d'une propriété de tableau associatif lorsque le nom de la propriété est un entier:

En commençant par un tableau associatif où les noms de propriétés sont des entiers:

var categories = [
    {"1": "Category 1"},
    {"2": "Category 2"},
    {"3": "Category 3"},
    {"4": "Category 4"}
];

Poussez les éléments vers la baie:

categories.push({"2300": "Category 2300"});
categories.push({"2301": "Category 2301"});

Parcourez le tableau et faites quelque chose avec la valeur de la propriété.

for (var i = 0; i < categories.length; i++) {
    for (var categoryid in categories[i]) {
        var category = categories[i][categoryid];
        // Log progress to the console
        console.log(categoryid + ": " + category);
        //  ... do something
    }
}

La sortie de la console devrait ressembler à ceci:

1: Category 1
2: Category 2
3: Category 3
4: Category 4
2300: Category 2300
2301: Category 2301

Comme vous pouvez le voir, vous pouvez contourner la limitation du tableau associatif et faire en sorte qu'un nom de propriété soit un entier.

REMARQUE: Le tableau associatif dans mon exemple est le contenu JSON que vous auriez si vous sérialisiez un objet Dictionary <string, string> [].



0

Parfois, j'utilise un préfixe pour mes clés. Par exemple:

var pre = 'foo',
    key = pre + 1234

obj = {};

obj[key] = val;

Maintenant, vous n'avez aucun problème à y accéder.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.