79 votes

Comment itérer les clés d'un tableau en Javascript ?

J'ai un tableau créé avec ce code :

var widthRange = new Array();
widthRange[46] = { min:0,  max:52 };
widthRange[66] = { min:52, max:70 };
widthRange[90] = { min:70, max:94 };

Je veux obtenir chacune des valeurs 46, 66, 90 dans une boucle. J'ai essayé for (var key in widthRange) mais cela me donne tout un tas de propriétés supplémentaires (je suppose que ce sont des fonctions sur l'objet). Je ne peux pas utiliser une boucle for normale puisque les valeurs ne sont pas séquentielles.

10 votes

On dirait que vous avez des données qui, bien qu'elles aient des clés numériques, ne sont pas réellement des données de tableau. J'envisagerais d'utiliser un objet ordinaire ici.

0 votes

@Quentin C'est ce qu'on appelle un tableau clairsemé. En termes de performances, il est préférable d'utiliser un tableau plutôt qu'un objet. De plus, du point de vue des performances, la meilleure réponse n'est même pas listée : Array.prototype.forEach . Appeler Object.keys sur un tableau est peu performant car les navigateurs ne sont pas optimisés pour cela. for(var key in array) est mauvais parce qu'il parcourt le prototype et met en chaîne chaque clé numérique qu'il rencontre (la conversion des doubles en base 10 est très lente). forEach a été conçu exactement pour l'itération de tableaux épars et offrira à votre code d'excellentes performances par rapport aux autres solutions.

97voto

SLaks Points 391154

Vous devez appeler le hasOwnProperty pour vérifier si la propriété est effectivement définie sur l'objet lui-même (par opposition à son prototype), comme ceci :

for (var key in widthRange) {
    if (key === 'length' || !widthRange.hasOwnProperty(key)) continue;
    var value = widthRange[key];
}

Notez que vous avez besoin d'un chèque séparé pour length .
Cependant, vous ne devriez pas du tout utiliser un tableau ici ; vous devriez utiliser un objet ordinaire. Tous les objets Javascript fonctionnent comme des tableaux associatifs.

Par exemple :

var widthRange = { };  //Or new Object()
widthRange[46] = { sel:46, min:0,  max:52 };
widthRange[66] = { sel:66, min:52, max:70 };
widthRange[90] = { sel:90, min:70, max:94 };

2 votes

Vraiment ? Wow, j'apprends quelque chose tous les jours ici, et c'est souvent grâce à vous, les SLaks :-) Je suis surpris que Array garde la trace de ses index explicitement définis de cette façon. Peut-être que je ne devrais pas l'être.

0 votes

@SLaks : Merci, le changer en objet semble la plus belle solution. Une autre question : existe-t-il un moyen d'itérer en ordre inverse ?

0 votes

Non, vous devez le faire vous-même.

86voto

thSoft Points 5513

Les clés stringifiées peuvent être interrogées avec Object.keys(array) .

6 votes

Cela renvoie les clés sous forme de chaînes de caractères, et non de chiffres, pour que tout le monde soit au courant.

0 votes

La meilleure solution... TY

0 votes

J'ai fait ma journée ! :D <3 Cela l'a résolu où array.keys() n'a rien donné.

18voto

Mike McKay Points 857

Si vous effectuez une quelconque manipulation ou inspection d'un tableau ou d'une collection, je vous recommande vivement d'utiliser la commande Underscore.js . Il est petit, bien testé et vous épargnera des jours/semaines/années de maux de tête en javascript. Voici sa fonction clé :

Clés

Récupère tous les noms des propriétés de l'objet.

_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]

0 votes

3voto

Pointy Points 172438
for (var i = 0; i < widthRange.length; ++i) {
  if (widthRange[i] != null) {
    // do something
  }
}

Vous ne pouvez pas vraiment obtenir uniquement les clés que vous avez définies, car ce n'est pas la façon dont un tableau fonctionne. Une fois que vous avez défini l'élément 46, vous avez également défini les éléments 0 à 45 (bien qu'ils soient nuls).

Vous pourriez toujours avoir deux les tableaux :

var widthRange = [], widths = [], newVal = function(n) {
  widths.push(n);
  return n;
};
widthRange[newVal(26)] = { whatever: "hello there" };

for (var i = 0; i < widths.length; ++i) {
  doSomething(widthRange[widths[i]]);
}

edit C'est peut-être que je suis tout mouillé ici...

0 votes

Les tableaux ne tiennent compte que de la longueur, ils ne créent pas d'objets. En fait, lorsqu'un nouvel indice est trouvé, on vérifie si ce nouvel indice est supérieur à la longueur... si c'est le cas, ce nouvel indice devient la nouvelle longueur. Pour cette raison, il est possible d'obtenir uniquement les index que vous avez définis avec une boucle for-in.

1voto

Andy Shellam Points 8120

Votre exemple original fonctionne très bien pour moi :

<html>
<head>
</head>
<body>
<script>
var widthRange = new Array();
widthRange[46] = { sel:46, min:0,  max:52 };
widthRange[66] = { sel:66, min:52, max:70 };
widthRange[90] = { sel:90, min:70, max:94 };

var i = 1;
for (var key in widthRange)
{
    document.write("Key #" + i + " = " + key + "; &nbsp;&nbsp;&nbsp; min/max = " + widthRange[key].min + "/" + widthRange[key].max + "<br />");
    i++;
}
</script>
</html>

Résultats dans le navigateur (Firefox 3.6.2 sur Windows XP) :

Key #1 = 46;     min/max = 0/52
Key #2 = 66;     min/max = 52/70
Key #3 = 90;     min/max = 70/94

2 votes

Je parie qu'il importe Prototype ou quelque chose comme ça. En général, ces boucles "in" sont risquées.

0 votes

J'utilise jQuery mais aussi Joomla qui utilise mootools, quelque chose ajoute ces propriétés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X