3802 votes

Boucle par le biais de tableau en JavaScript

En Java, vous pouvez utiliser un for() boucle pour parcourir les objets dans un tableau comme ceci:

String[] myStringArray = {"Hello","World"};
for(String s : myStringArray)
{
    //Do something
}

Pouvez-vous faire la même chose en JavaScript?

4899voto

CMS Points 315406

L'utilisation d'un séquentiel for boucle:

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    alert(myStringArray[i]);
    //Do something
}

@zipcodeman suggère l'utilisation de l' for...in déclaration, mais pour l'itération tableaux for-in devrait être évitée, cette déclaration est destinée à énumérer les propriétés de l'objet.

Il ne devrait pas être utilisé pour tableau d'objets similaires parce que:

  • L'ordre d'itération n'est pas garanti, les indices de tableau ne peut pas être visité dans l'ordre numérique.
  • Les propriétés héritées sont également énumérés.

Le deuxième point est qu'il peut vous donner beaucoup de problèmes, par exemple, si vous prolongez l' Array.prototype objet à inclure une méthode, et cette propriété sera également énumérés.

Par exemple:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
  alert(array[i]);
}

Le code ci-dessus alerte, "a", "b", "c" et "foo!".

Que être un problème si vous utilisez une bibliothèque qui s'appuie fortement sur les prototypes augmention (comme MooTools par exemple).

L' for-in déclaration comme je l'ai dit avant, il est là pour énumérer les propriétés de l'objet, par exemple:

var obj = {
  "a": 1,
  "b": 2,
  "c": 3
};

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) { 
  // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
    alert("prop: " + prop + " value: " + obj[prop])
  }
}

Dans l'exemple ci-dessus l' hasOwnProperty méthode permet d'énumérer seulement propres propriétés, c'est ça, seulement les propriétés de l'objet physiquement a pas de propriétés héritées.

Je vous recommande de lire l'article suivant:

1169voto

Mark Reed Points 23817

Pour répondre à la question: non, vous ne pouvez pas. Le JavaScript n'a pas une syntaxe concise pour parcourir des Tableaux. Au moins, pas de manière universelle.

Si vous voulez le code qui est à la fois efficace et universelle (qui est, il fonctionne dans tous les navigateurs et autres js interprètes), vous devez utiliser explicitement un comptage de la boucle. La version la plus sûre, qui manipule des matrices creuses correctement, est-ce:

var myStringArray = [ "Hello", "World" ]
var len = myStringArray.length
for (var i=0; i<len; ++i) {
  if (i in myStringArray) {
    var s = myStringArray[i];
    ... do something with s ...
  }
}

Affectation de la valeur de la longueur de la variable locale (par opposition à l'inclusion de la pleine myStringArray.length de l'expression de la condition de la boucle) peut faire une différence significative dans la performance; à l'aide de Rhino sur ma machine, l'accélération est de 43%.

Si vous êtes prêt à vous restreindre à un sous-ensemble de la disposition des moteurs JavaScript, vous pouvez utiliser l'interface de bouclage méthode forEach, ce qui prend une fonction qui est appelée une fois par élément dans le tableau, et gère automatiquement les matrices creuses correctement:

var myStringArray = [ "Hello", "World" ]
myStringArray.forEach( function(s) { 
     ... do something with s ...
} )

La performance de l' forEach fait beats explicite de comptage de la boucle locale pour la longueur de la var par un facteur de 2 à SpiderMonkey (encore une fois, sur ma machine). Il est plus lent dans Rhino, mais à peine, tout en étant plus rapide que le comptage de la boucle sans cache le var.

L' for...in de la syntaxe mentionné par d'autres, est pour boucler sur les propriétés d'un objet; depuis un Tableau en JavaScript est juste un objet numérique noms de propriété (et magique de la "longueur" de la propriété), vous pouvez théoriquement en boucle sur un Tableau avec elle. Mais le problème est qu'il ne se limite pas à la propriété numérique des valeurs, et en JavaScript, même les méthodes sont en fait juste des propriétés dont la valeur est une fermeture. Par conséquent, l' for...in de la syntaxe doit pas être utilisé pour la lecture en boucle par le biais de réseaux. (Il n'est pas si grand pour des Objets génériques à être utilisées comme des cartes/hachages/dictionnaires, soit, pour être honnête.)

452voto

hasenj Points 36139

Vous pouvez utiliser map (également connu en tant que apply dans d'autres langages comme python, et probablement haskell trop)

[1,2,3,4].map( function(item) {
     alert(item);
})

La syntaxe générale est:

array.map(func)

func devrait prendre un paramètre.

La valeur de retour de l' array.map est un autre tableau, de sorte que vous pouvez l'utiliser comme ceci:

var x = [1,2,3,4].map( function(item) { return item * 10; } );

Et maintenant x est [10,20,30,40]

EDIT:

Je dois préciser: ce concept est à partir du paradigme fonctionnel.

Vous n'avez pas à écrire la fonction inline; on peut le faire comme une première esquisse, mais vous pouvez l'extraire dans sa propre fonction.

var item_processor = function(item) {
      // do something complicated to an item 
}

new_list = my_list.map(item_processor);

ce qui serait un peu de l'équivalent de:

 for(item in my_list) { item_processor(item); }

sauf que vous n'obtenez pas l' new_list.

130voto

sebarmeli Points 11831

En JavaScript, il n'est pas conseillé de parcourir un Tableau avec un pour-en boucle, mais c'est mieux à l'aide d'une boucle for, tels que:

for(var i=0, len=myArray.length; i < len; i++){}

Il est optimisé ("mise en cache" la longueur du tableau). Si vous souhaitez en savoir plus, lire mon post sur le sujet.

93voto

kennebec Points 33886

Opera, Safari, Firefox et Chrome maintenant, tous partagent un ensemble de amélioré les méthodes de Tableau pour l'optimisation de nombreuses boucles.

Vous ne pouvez pas besoin de tout d'eux, mais ils peuvent être très utiles, ou qui le seraient si tous les navigateurs pris en charge.

Le mozilla labs a publié les algorithmes et webkit, à la fois, de sorte que vous pouvez les ajouter vous-même.

filtre retourne un tableau d'objets qui satisfont à des conditions ou à des test.

tous les renvoie la valeur true si chaque membre du groupe passe le test.

certains renvoie true si tout passer le test.

forEach exécute une fonction sur chaque membre du groupe et ne retourne rien.

la carte est comme forEach, mais elle renvoie un tableau des résultats de l'opération pour chaque élément.

Ces méthodes prennent tous une fonction pour le premier argument, et avoir un deuxième argument optionnel, qui est un objet dont la portée que vous voulez imposer sur le tableau les membres de la boucle à travers la fonction.

L'ignorer jusqu'à ce que vous en avez besoin.

indexOf et lastIndexOf trouver la position appropriée de le premier ou le dernier élément qui correspond à son argument exactement.

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this)) return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what) return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L) i= L-1;
            else if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what) return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this)) return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p]) ap[p]= p2[p];
    }
    return true;
})();

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