web-dev-qa-db-fra.com

Pour chacun sur un tableau en JavaScript?

Comment puis-je parcourir toutes les entrées d'un tableau en utilisant JavaScript?

Je pensais que c'était quelque chose comme ça:

forEach(instance in theArray)

theArray est mon tableau, mais cela semble être incorrect.

4056
Dante1986

TL; DR

  • N'utilisez pas _for-in_ sauf si vous l'utilisez avec des sauvegardes ou si vous êtes au moins conscient de la raison pour laquelle il pourrait vous mordre.
  • Vos meilleurs paris sont généralement

    • une boucle _for-of_ (ES2015 + uniquement),
    • _Array#forEach_ ( spec | MDN ) (ou ses proches some et autres) (ES5 + uniquement),
    • une simple boucle for à l'ancienne,
    • ou _for-in_ avec sauvegardes.

Mais il y alotsplus à explorer, lisez la suite ...


JavaScript possède une sémantique puissante pour la boucle dans les tableaux et les objets semblables à des tableaux. J'ai divisé la réponse en deux parties: Options pour les tableaux authentiques et options pour les éléments qui ne sont que des tableaux - comme , tels que l'objet arguments, d'autres objets itérables (ES2015 +), DOM collections, etc.

Je noterai rapidement que vous pouvez utiliser les options ES2015 maintenant , même sur les moteurs ES5, en transpiler ES2015 à ES5. Recherche de "ES2015 transpiling"/"ES6 transpiling" pour plus ...

Ok, regardons nos options:

Pour les tableaux réels

Vous avez trois options dans ECMAScript 5 ("ES5"), la version la plus largement prise en charge pour le moment, et deux autres ajoutées dans ECMAScript 2015 ("ES2015", "ES6") :

  1. Utilisez forEach et connexes (ES5 +)
  2. Utilisez une simple boucle for
  3. Utilisez _for-in_ correctement
  4. Utilisez _for-of_ (utilisez implicitement un itérateur) (ES2015 +)
  5. Utiliser explicitement un itérateur (ES2015 +)

Détails:

1. Utilisez forEach et connexe

Dans tout environnement vaguement moderne (donc pas IE8) où vous avez accès aux fonctionnalités Array ajoutées par ES5 (directement ou à l'aide de polyfill), vous pouvez utiliser forEach ( spec | MDN ):

_var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});_

forEach accepte une fonction de rappel et, éventuellement, une valeur à utiliser en tant que this lors de l'appel de ce rappel (non utilisé ci-dessus). Le rappel est appelé pour chaque entrée du tableau, dans l'ordre, en ignorant les entrées inexistantes dans les tableaux fragmentés. Bien que je n’ai utilisé qu’un seul argument ci-dessus, le rappel est appelé avec trois: la valeur de chaque entrée, l’index de cette entrée et une référence au tableau sur lequel vous effectuez une itération (au cas où votre fonction ne l’aurait pas déjà à portée de main) ).

À moins que vous ne preniez en charge des navigateurs obsolètes tels que IE8 (dont NetApps affiche une part de marché légèrement supérieure à 4% à la date de rédaction de ce rapport en septembre 2016), vous pouvez utiliser forEach dans une page Web à usage général sans cale. Si vous devez prendre en charge des navigateurs obsolètes, le calage/le remplissage de forEach se fait facilement (recherchez "es5 shim" pour plusieurs options).

forEach a l'avantage de ne pas avoir à déclarer les variables d'indexation et de valeur dans la portée qui les contient, car elles sont fournies en tant qu'arguments de la fonction d'itération, et sont donc parfaitement adaptées à cette itération.

Si le coût d'exécution d'un appel de fonction pour chaque entrée de tableau vous inquiète, ne le soyez pas; détails .

De plus, forEach est la fonction "En boucle entre eux", mais ES5 a défini plusieurs autres fonctions utiles "Parcourez le tableau et effectuez des actions", notamment:

  • every (arrête de boucler la première fois que le rappel retourne false ou quelque chose de similaire)
  • some (arrête de boucler la première fois que le rappel retourne true ou quelque chose de vrai)
  • filter (crée un nouveau tableau comprenant des éléments pour lesquels la fonction de filtrage renvoie true et en omettant ceux pour lesquels il renvoie false)
  • map (crée un nouveau tableau à partir des valeurs renvoyées par le rappel)
  • reduce (construit une valeur en appelant plusieurs fois le rappel, en transmettant les valeurs précédentes; voir la spécification pour les détails; utile pour faire la somme du contenu d'un tableau et pour bien d'autres choses)
  • reduceRight (comme reduce, mais fonctionne par ordre décroissant plutôt que croissant)

2. Utilisez une simple boucle for

Parfois, les anciennes méthodes sont les meilleures:

_var index;
var a = ["a", "b", "c"];
for (index = 0; index < a.length; ++index) {
    console.log(a[index]);
}_

Si la longueur du tableau ne change pas pendant la boucle et que le code est sensible aux performances (improbable), une version un peu plus compliquée prenant la longueur à l’avant pourrait bien être un minuscule bit plus rapide:

_var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}_

Et/ou compte à rebours:

_var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}_

Mais avec les moteurs JavaScript modernes, il est rare que vous ayez besoin de ce dernier coup de pouce.

Dans ES2015 et versions ultérieures, vous pouvez associer vos variables d'index et de valeur à la boucle for:

_let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
    console.log(index, value);
}
//console.log(index);   // would cause "ReferenceError: index is not defined"
//console.log(value);   // would cause "ReferenceError: value is not defined"
_
_let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
    console.log(index, value);
}
try {
    console.log(index);
} catch (e) {
    console.error(e);   // "ReferenceError: index is not defined"
}
try {
    console.log(value);
} catch (e) {
    console.error(e);   // "ReferenceError: value is not defined"
}_

Et lorsque vous faites cela, non seulement value, mais aussi index est recréé pour chaque itération de boucle, ce qui signifie que les fermetures créées dans le corps de la boucle gardent une référence au index (et value) créé pour cette itération spécifique:

_let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        console.log("Index is: " + index);
    });
}
_
_let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        console.log("Index is: " + index);
    });
}_
_<div>zero</div>
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>_

Si vous aviez cinq divs, vous obtiendrez "Index is: 0" si vous avez cliqué sur le premier et "Index is: 4" si vous avez cliqué sur le dernier. Cela fonctionnenotsi vous utilisez var au lieu de let.

3. Utilisez _for-in_ correctement

Vous obtiendrez des personnes qui vous diront d'utiliser _for-in_, mais ce n'est pas ce que _for-in_ est pour . _for-in_ parcourt les propriétés énumérables d'un objet et non les index d'un tableau.La commande n'est pas garantie, pas même dans ES2015 (ES6). ES2015 + définit un ordre pour les propriétés d'objet (via [[OwnPropertyKeys]] , [[Enumerate]] et les choses qui les utilisent comme Object.getOwnPropertyKeys ), maisne/ne définit pas que _for-in_ suivra cet ordre. (Détails dans cette autre réponse .)

Les seuls cas d'utilisation réels de _for-in_ sur un tableau sont les suivants:

  • C'est un tableaux épars avecmassifespaces, ou
  • Vous utilisez des propriétés non-élément et vous souhaitez les inclure dans la boucle

En regardant seulement ce premier exemple: Vous pouvez utiliser _for-in_ pour visiter ces éléments de tableau sparais si vous utilisez les sauvegardes appropriées:

_// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These checks are
        /^0$|^[1-9]\d*$/.test(key) &&    // explained
        key <= 4294967294                // below
        ) {
        console.log(a[key]);
    }
}_

Notez les trois contrôles:

  1. Que l'objet possède sa propriété propre portant ce nom (et non un héritage de son prototype), et

  2. Que la clé est composée uniquement de chiffres décimaux (par exemple, forme de chaîne normale, pas de notation scientifique), et

  3. Que la valeur de la clé lorsque contraint à un nombre est <= 2 ^ 32 - 2 (qui est 4,294,967,294). D'où vient ce nombre? Cela fait partie de la définition d'un indice de tableau dans la spécification . Les autres nombres (non-entiers, nombres négatifs, nombres supérieurs à 2 ^ 32 - 2) ne sont pas des index de tableau. La raison pour laquelle il s’agit de 2 ^ 32 -2est que la plus grande valeur de l’index est inférieure à 2 ^ 32 -1, qui est la valeur maximale d’un tableau length peut avoir. (Par exemple, la longueur d'un tableau correspond à un entier non signé de 32 bits.) (Merci à RobG pour avoir souligné dans un commentaire sur mon blog que mon test précédent n'était pas tout à fait correct .)

Vous ne feriez pas cela dans le code en ligne, bien sûr. Vous écririez une fonction utilitaire. Peut-être:

_// Utility function for antiquated environments without `forEach`
var hasOwn = Object.prototype.hasOwnProperty;
var rexNum = /^0$|^[1-9]\d*$/;
function sparseEach(array, callback, thisArg) {
    var index;
    for (var key in array) {
        index = +key;
        if (hasOwn.call(a, key) &&
            rexNum.test(key) &&
            index <= 4294967294
            ) {
            callback.call(thisArg, array[key], index, array);
        }
    }
}

var a = [];
a[5] = "five";
a[10] = "ten";
a[100000] = "one hundred thousand";
a.b = "bee";

sparseEach(a, function(value, index) {
    console.log("Value at " + index + " is " + value);
});_

4. Utilisez _for-of_ (utilisez implicitement un itérateur) (ES2015 +)

ES2015 ajoute des itérateurs à JavaScript. Le moyen le plus simple d'utiliser des itérateurs est la nouvelle instruction _for-of_. Cela ressemble à ceci:

_const a = ["a", "b", "c"];
for (const val of a) {
    console.log(val);
}_

Sous les couvertures, cela obtient un itérateur du tableau et le parcourt, en obtenant les valeurs. Cela n'a pas le problème que l'utilisation de _for-in_ a, car il utilise un itérateur défini par l'objet (le tableau), et les tableaux définissent que leurs itérateurs itèrent à travers leurs entrées (pas leurs propriétés). Contrairement à _for-in_ dans ES5, l'ordre dans lequel les entrées sont visitées est l'ordre numérique de leurs index.

5. Utiliser explicitement un itérateur (ES2015 +)

Parfois, vous pouvez utiliser un itérateur explicitement . Vous pouvez le faire aussi, même si c'est beaucoup plus encombrant que _for-of_. Cela ressemble à ceci:

_const a = ["a", "b", "c"];
const it = a.values();
let entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}_

L'itérateur est un objet correspondant à la définition d'Iterator dans la spécification. Sa méthode next renvoie un nouvel objet de résultat à chaque appel. L'objet de résultat a une propriété, done, nous indiquant si c'est fait, et une propriété value avec la valeur de cette itération. (done est optionnel si ce serait false, value est optionnel s'il était undefined.)

La signification de value varie selon l’itérateur; Les tableaux prennent en charge (au moins) trois fonctions renvoyant des itérateurs:

  • values(): C'est celui que j'ai utilisé ci-dessus. Il renvoie un itérateur où chaque value est l'entrée du tableau pour cette itération (_"a"_, _"b"_ et _"c"_ dans l'exemple précédent).
  • keys(): Retourne un itérateur où chaque value est la clé de cette itération (donc pour notre a ci-dessus, ce serait _"0"_, puis _"1"_, puis _"2"_).
  • entries(): renvoie un itérateur où chaque value est un tableau de la forme _[key, value]_ pour cette itération.

Pour les objets de type tableau

En plus des tableaux réels, il existe également des objets de type tableau dotés d'une propriété length et de propriétés portant des noms numériques: instances NodeList, objet arguments, etc. Comment pouvons-nous parcourir leur contenu?

Utilisez l’une des options ci-dessus pour les tableaux.

Au moins certaines, et peut-être même la plupart, voire toutes les approches de tableau ci-dessus s'appliquent également aux objets de type tableau:

  1. Utilisez forEach et connexes (ES5 +)

    Les différentes fonctions de _Array.prototype_ sont "intentionnellement génériques" et peuvent généralement être utilisées sur des objets de type tableau via Function#call ou Function#apply . (Voir l'avertissement relatif aux objets fournis par l'hôte à la fin de cette réponse, mais il s'agit d'un problème rare.)

    Supposons que vous souhaitiez utiliser forEach sur la propriété Node's childNodes. Tu ferais ça:

    _Array.prototype.forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    _

    Si vous envisagez beaucoup de choses, vous pouvez extraire une copie de la référence de la fonction dans une variable pour la réutiliser, par exemple:

    _// (This is all presumably in some scoping function)
    var forEach = Array.prototype.forEach;
    
    // Then later...
    forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    _
  2. Utilisez une simple boucle for

    De toute évidence, une simple boucle for s'applique aux objets de type tableau.

  3. Utilisez _for-in_ correctement

    _for-in_ avec les mêmes protections que pour un tableau devrait également fonctionner avec des objets de type tableau; l'avertissement pour les objets fournis par l'hôte au n ° 1 ci-dessus peut s'appliquer.

  4. Utilisez _for-of_ (utilisez implicitement un itérateur) (ES2015 +)

    _for-of_ utilisera l'itérateur fourni par l'objet (le cas échéant); nous devrons voir comment cela joue avec les divers objets de type tableau, en particulier ceux fournis par l'hôte. Par exemple, la spécification pour NodeList de querySelectorAll a été mise à jour pour prendre en charge l'itération. La spécification pour le HTMLCollection de getElementsByTagName ne l’était pas.

  5. Utiliser explicitement un itérateur (ES2015 +)

    Voir n ° 4, nous devrons voir comment les itérateurs jouent.

Créer un vrai tableau

D'autres fois, vous voudrez peut-être convertir un objet semblable à un tableau en un vrai tableau. Faire cela est étonnamment facile:

  1. Utilisez la méthode slice des tableaux

    Nous pouvons utiliser la méthode de tableaux slice, qui, comme les autres méthodes mentionnées ci-dessus, est "intentionnellement générique" et peut donc être utilisée avec des objets de type tableau, comme ceci:

    _var trueArray = Array.prototype.slice.call(arrayLikeObject);
    _

    Ainsi, par exemple, si nous voulons convertir un NodeList en un tableau vrai, nous pourrions faire ceci:

    _var divs = Array.prototype.slice.call(document.querySelectorAll("div"));
    _

    Voir la mise en garde concernant les objets fournis par l'hôte ci-dessous. En particulier, notez que cela échouera dans IE8 et les versions antérieures, ce qui ne vous permettra pas d'utiliser des objets fournis par l'hôte sous la forme this comme cela.

  2. Utiliser répandre la syntaxe (_..._)

    Il est également possible d'utiliser la syntaxe spread de ES2015 avec des moteurs JavaScript prenant en charge cette fonctionnalité:

    _var trueArray = [...iterableObject];
    _

    Ainsi, par exemple, si nous voulons convertir un NodeList en un vrai tableau, avec une syntaxe étendue, cela devient assez succinct:

    _var divs = [...document.querySelectorAll("div")];
    _
  3. Utilisez _Array.from_(spec) | (MDN)

    _Array.from_ (ES2015 +, mais polyfilled facilement) crée un tableau à partir d'un objet de type tableau, en passant éventuellement les entrées à travers une fonction de mappage. Alors:

    _var divs = Array.from(document.querySelectorAll("div"));
    _

    Ou si vous voulez obtenir un tableau des noms de balises des éléments avec une classe donnée, utilisez la fonction de mappage:

    _// Arrow function (ES2015):
    var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);
    
    // Standard function (since `Array.from` can be shimmed):
    var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
        return element.tagName;
    });
    _

Mise en garde pour les objets fournis par l'hôte

Si vous utilisez des fonctions _Array.prototype_ avec des objets de type tableau fournis par l'hôte (listes DOM et autres éléments fournis par le navigateur plutôt que par le moteur JavaScript), vous devez vous assurer de: Testez dans vos environnements cibles pour vous assurer que l'objet fourni par l'hôte se comporte correctement.La plupart se comportent correctement(maintenant), mais il est important de tester. La raison en est que la plupart des méthodes _Array.prototype_ que vous voudrez probablement utiliser dépendent de l'objet fourni par l'hôte qui donne une réponse honnête à l'opération abstract [[HasProperty]] . Au moment d'écrire ces lignes, les navigateurs font un très bon travail dans ce domaine, mais la spécification 5.1 permettait la possibilité qu'un objet fourni par l'hôte ne soit pas honnête. C'est dans §8.6.2 , plusieurs paragraphes en dessous de la grande table vers le début de cette section), où il est écrit:

Les objets hôtes peuvent implémenter ces méthodes internes de n'importe quelle manière, sauf indication contraire. Par exemple, une possibilité est que _[[Get]]_ et _[[Put]]_ pour un objet hôte particulier récupère et stocke les valeurs de propriété, mais _[[HasProperty]]_ génère toujoursfalse.

(Je ne pouvais pas trouver le verbiage équivalent dans la spécification ES2015, mais il est certain que ce sera toujours le cas.) Encore une fois, à la date de cette écriture, les objets communs de type tableau fournis par l'hôte dans les navigateurs modernes [NodeList instances, par exemple]dohandle _[[HasProperty]]_ correctement, mais il est important de tester.)

6662
T.J. Crowder

Edit: Cette réponse est désespérément obsolète. Pour une approche plus moderne, regardez les méthodes disponibles sur un tableau . Les méthodes d'intérêt pourraient être:

  • pour chaque
  • carte
  • filtre
  • Zip *: français
  • réduire
  • chaque
  • certains

La méthode standard pour itérer un tableau dans JavaScript est une boucle Vanilla for-:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

Notez cependant que cette approche n’est utile que si vous avez un tableau dense et que chaque index est occupé par un élément. Si le tableau est clairsemé, vous pouvez rencontrer des problèmes de performances avec cette approche, car vous effectuerez une itération sur un grand nombre d'indices qui n'existent pas vraiment dans le tableau. Dans ce cas, une boucle for .. in- pourrait être une meilleure idée. Cependant, vous devez utiliser les sauvegardes appropriées pour vous assurer que seules les propriétés souhaitées du tableau (c'est-à-dire les éléments du tableau) sont utilisées, car la boucle for..in- sera également énumérée dans les anciens navigateurs, ou si le les propriétés supplémentaires sont définies en tant que enumerable.

Dans ECMAScript 5 , il y aura une méthode forEach sur le prototype de tableau, mais elle n'est pas prise en charge par les navigateurs hérités. Donc, pour pouvoir l'utiliser de manière cohérente, vous devez disposer d'un environnement qui le prend en charge (par exemple, Node.js pour JavaScript côté serveur) ou utiliser un "Polyfill". Le Polyfill pour cette fonctionnalité est cependant trivial et, puisqu'il facilite la lecture du code, il est bon de l'inclure.

473
PatrikAkerstrand

Si vous utilisez la bibliothèque jQuery , vous pouvez utiliser jQuery.each :

$.each(yourArray, function(index, value) {
  // do your stuff here
});

MODIFIER : 

Selon la question, l’utilisateur veut du code en javascript au lieu de jquery afin que la modification soit

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}
214
Poonam

Certains langages de style C - utilisent foreach pour parcourir les énumérations en boucle. En JavaScript, cela se fait avec la structure de boucle for..in :

var index,
    value;
for (index in obj) {
    value = obj[index];
}

Il y a une prise. for..in parcourt chacun des membres énumérables de l'objet et les membres de son prototype. Pour éviter de lire les valeurs héritées du prototype de l'objet, vérifiez simplement si la propriété appartient à l'objet:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

De plus, ECMAScript 5 a ajouté une méthode forEach à Array.prototype qui peut être utilisée pour énumérer un tableau à l'aide d'un calback (le polyfill se trouve dans la documentation afin que vous puissiez toujours l'utiliser pour les navigateurs plus anciens):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

Il est important de noter que Array.prototype.forEach ne s'interrompt pas lorsque le rappel retourne false. jQuery et Underscore.js fournissent leurs propres variations sur each afin de fournir des boucles pouvant être court-circuitées.

75
zzzzBov

Si vous souhaitez effectuer une boucle sur un tableau, utilisez la boucle for standard en trois parties.

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

Vous pouvez obtenir certaines optimisations de performances en mettant en cache myArray.length ou en effectuant une itération inverse.

34
Quentin

Si cela ne vous dérange pas de vider le tableau:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

x contiendra la dernière valeur de y et elle sera supprimée du tableau. Vous pouvez également utiliser shift() qui donnera et supprimera le premier élément de y.

27
gaby de wilde

Une implémentation de forEach ( voir dans jsFiddle ):

function forEach(list,callback) {
  var length = list.length;
  for (var n = 0; n < length; n++) {
    callback.call(list[n]);
  }
}

var myArray = ['hello','world'];

forEach(
  myArray,
  function(){
    alert(this); // do something
  }
);
27
nmoliveira

Une solution simple consisterait maintenant à utiliser la bibliothèque underscore.js . Il fournit de nombreux outils utiles, tels que each, et déléguera automatiquement le travail à la variable forEach si disponible.

Un exemple de CodePen de comment cela fonctionne est:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

Voir également

24
Micka

Il existe trois implémentations de foreach dans jQuery comme suit.

var a = [3,2];

$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3
24
Rajesh Paul

La boucle for(i = 0; i < array.length; i++) n'est probablement pas le meilleur choix. Pourquoi? Si vous avez ceci:

var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";

La méthode appellera de array[0] à array[2]. Premièrement, ceci va tout d'abord référencer les variables que vous n'avez même pas, ensuite vous n'auriez pas les variables dans le tableau, et troisièmement, cela rendra le code plus gras. Regardez ici, c'est ce que j'utilise:

for(var i in array){
    var el = array[i];
    //If you want 'i' to be INT just put parseInt(i)
    //Do something with el
}

Et si vous voulez que ce soit une fonction, vous pouvez faire ceci:

function foreach(array, call){
    for(var i in array){
        call(array[i]);
    }
}

Si vous voulez rompre, un peu plus de logique:

function foreach(array, call){
    for(var i in array){
        if(call(array[i]) == false){
            break;
        }
    }
}

Exemple:

foreach(array, function(el){
    if(el != "!"){
        console.log(el);
    } else {
        console.log(el+"!!");
    }
});

Il retourne:

//Hello
//World
//!!!
22
Federico Piragua

À partir de ES6:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

of évite les bizarreries associées à in et la fait fonctionner comme la boucle for de toute autre langue, et let lie i dans la boucle et non dans la fonction.

Les accolades ({}) peuvent être omises lorsqu'il n'y a qu'une seule commande (par exemple, dans l'exemple ci-dessus).

21
Zaz

Il s’agit d’un itérateur pour une liste non fragmentée dont l’index commence à 0, ce qui est le scénario typique lorsqu’il s’agit de document.getElementsByTagName ou document.querySelectorAll)

function each( fn, data ) {

    if(typeof fn == 'string')
        eval('fn = function(data, i){' + fn + '}');

    for(var i=0, L=this.length; i < L; i++) 
        fn.call( this[i], data, i );   

    return this;
}

Array.prototype.each = each;  

Exemples d'utilisation:

Exemple 1

var arr = [];
[1, 2, 3].each( function(a){ a.Push( this * this}, arr);
arr = [1, 4, 9]

Exemple # 2

each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

Chaque balise p reçoit class="blue"

Exemple # 3

each.call(document.getElementsByTagName('p'), 
    "if( i % 2 == 0) this.className = data;",
    'red'
);

Chaque autre balise p reçoit class="red">

Exemple # 4

each.call(document.querySelectorAll('p.blue'), 
    function(newClass, i) {
        if( i < 20 )
            this.className = newClass;
    }, 'green'
);

Et enfin, les 20 premiers tags p bleus sont changés en vert

Attention lors de l'utilisation de chaîne comme fonction: la fonction est créée hors contexte et ne doit être utilisée que si vous êtes certain de la portée des variables. Sinon, il vaut mieux passer les fonctions où la portée est plus intuitive.

17
Tim

Il n'y a pas de boucle for each en natif JavaScript . Vous pouvez utiliser les bibliothèques pour obtenir cette fonctionnalité (je recommande Underscore.js ), utilisez une simple boucle for in.

for (var instance in objects) {
   ...
}

Cependant, notez qu'il peut y avoir des raisons d'utiliser une boucle for encore plus simple (voir la question Débordement de pile Pourquoi l'utilisation de “for… in” avec une itération de tableau est-elle une si mauvaise idée?)

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}
17
joidegn

Il y a quelques façons de parcourir un tableau en JavaScript, comme ci-dessous:

pour - c'est le plus commun. Bloc complet de code pour la mise en boucle

var languages = ["Java", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

while - boucle lorsqu'une condition est remplie. Cela semble être la boucle la plus rapide

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

do/while - Parcourt également un bloc de code lorsque la condition est vraie et s'exécutera au moins une fois.

var text = ""
var i = 0;
do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>

Boucles fonctionnelles - forEach, map, filter, aussi reduce (ils parcourent la fonction en boucle, mais sont utilisés si vous avez besoin de modifier votre tableau, etc.

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>

Pour plus d'informations et d'exemples sur la programmation fonctionnelle de tableaux, consultez l'article de blog Programmation fonctionnelle en JavaScript: mapper, filtrer et réduire.

16
Alireza

ECMAScript5 (la version sur Javascript) pour travailler avec des tableaux.

forEach - Itère à travers tous les éléments du tableau et fait tout ce dont vous avez besoin avec chaque élément.

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is the #" + (index+1) + " in musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

Au cas où, plus intéressé par le fonctionnement sur tableau en utilisant une fonctionnalité intégrée.

map - Il crée un nouveau tableau avec le résultat de la fonction de rappel. Cette méthode est utile si vous avez besoin de formater les éléments de votre tableau.

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

reduction - Comme son nom l'indique, il réduit le tableau à une valeur unique en appelant la fonction donnée transmettant l'élément currenct et le résultat de l'exécution précédente.

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

every - Renvoie true ou false si tous les éléments du tableau réussissent le test de la fonction de rappel.

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];  
ages.every(function(elem) {  
  return elem >= 18;
});

// Output: false

filter - Très similaire à tous sauf que filter retourne un tableau avec les éléments qui retournent true à la fonction donnée.

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]

J'espère que cela vous sera utile.

14
Anil Kumar Arya

Il n'y a pas de capacité incorporée à roder forEach. Pour interrompre l'exécution, utilisez le Array#some comme ci-dessous:

[1,2,3].some(function(number) {
    return number === 1;
});

Cela fonctionne car some renvoie true dès que l'un des rappels, exécuté dans l'ordre du tableau, renvoie true, court-circuitant l'exécution du reste. Réponse originale Voir le prototype de tableau pour some

14
Priyanshu Chauhan

J'aimerais également ajouter ceci en tant que composition d'une boucle inversée et réponse ci-dessus à quelqu'un qui aimerait aussi cette syntaxe.

var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

Avantages:

L'avantage pour cela: vous avez déjà la référence dans la première, car il ne sera pas nécessaire de la déclarer ultérieurement avec une autre ligne. C'est pratique lorsque vous passez en boucle dans le tableau d'objets.

Les inconvénients:

Cela cassera chaque fois que la référence est fausse - falsey (indéfini, etc.). Il peut être utilisé comme avantage cependant. Cependant, cela rendrait la lecture un peu plus difficile. Et également en fonction du navigateur, il peut être "non" optimisé pour fonctionner plus rapidement que celui d'origine.

11

manière jQuery utilisant $.map:

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];
10
DanFromGermany

Une méthode plus proche de votre idée serait d’utiliser Array.forEach() qui accepte une fonction de verrouillage qui sera exécutée pour chaque élément du tableau.

myArray.forEach(
  (item) => {
    // do something 
    console.log(item);
  }
);

Une autre solution viable consisterait à utiliser Array.map() qui fonctionne de la même manière, mais aussi à mutates chaque élément et le renvoie comme suit:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);

console.log(myArray); // [2, 3, 4]
6

Utilisation des boucles avec ES6 déstructuration et opérateur d'étalement

La destruction et l'utilisation de l'opérateur de propagation se sont révélées très utiles pour les nouveaux arrivants à ES6, car ils sont plus lisibles/esthétiques, bien que certains anciens combattants du javascript puissent le considérer comme désordonné, que des juniors ou d'autres personnes puissent le trouver utile.

Les exemples suivants utiliseront l'instruction for...of et la méthode .forEach .

Les exemples 6, 7 et 8 peuvent être utilisés avec toutes les boucles fonctionnelles telles que .map, .filter, .reduce, .sort, .every, .some, pour plus d'informations sur ces méthodes, consultez le Array Object .

Exemple 1: Normal for...of loop - pas d'astuce ici.

let arrSimple = ['a', 'b', 'c'];

for (let letter of arrSimple) {
  console.log(letter);
}

Exemple 2: Fractionner des mots en caractères

let arrFruits = ['Apple', 'orange', 'banana'];

for (let [firstLetter, ...restOfTheWord] of arrFruits) {
  // Create a shallow copy using the spread operator
  let [lastLetter] = [...restOfTheWord].reverse();
  console.log(firstLetter, lastLetter, restOfTheWord);

}

Exemple 3: Boucle avec une key et value 

// let arrSimple = ['a', 'b', 'c'];

// Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)`
// this example will use a multi-dimensional array of the following format type: 
// `arrWithIndex: [number, string][]`

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Same thing can be achieved using `.map` method
// let arrWithIndex = arrSimple.map((i, idx) => [idx, i]);

// Same thing can be achieved using `Object.entries`
// NOTE: `Object.entries` method doesn't work on internet Explorer unless it's polyfilled
// let arrWithIndex = Object.entries(arrSimple);

for (let [key, value] of arrWithIndex) {
  console.log(key, value);
}

Exemple 4: Obtenir les propriétés de l'objet en ligne

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];

for (let { name, age: aliasForAge } of arrWithObjects) {
  console.log(name, aliasForAge);
}

Exemple 5: Obtenir les propriétés de l'objet dont vous avez besoin

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) {
  console.log(name, firstItemFromTags, restOfTags);
}

Exemple 6: Est Exemple 3 utilisé avec .forEach

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Not to be confused here, `forEachIndex` is the real index
// `mappedIndex` was created by "another user", so you can't really trust it

arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => {
  console.log(forEachIndex, mappedIndex, item);
});

Exemple 7: Est Exemple 4 utilisé avec .forEach

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];
// NOTE: Destructuring objects while using shorthand functions 
// are required to be surrounded by parenthesis
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
  console.log(name, aliasForAge)
});

Exemple 8: Est Exemple 5 utilisé avec .forEach

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

arrWithObjectsWithArr.forEach(({
  name,
  tags: [firstItemFromTags, ...restOfTags]
}) => {
  console.log(name, firstItemFromTags, restOfTags);
});

6
darklightcode

La syntaxe lambda ne fonctionne généralement pas dans IE 10 ou moins.

J'utilise habituellement le

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});


If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters

$("#ul>li").each(function(**index,value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});
5
Murtuza Husain

Vous pouvez appeler pour chaque chose comme ceci:

let Array = [1,3,2];

theArray.forEach((element)=>{ 
  // use the element of the array
  console.log(element) 
}

element aura la valeur de chaque index de 0 a la longueur du tableau.

Sortie:

1    
3    
2

Explication

forEach est dans la classe prototype. vous pouvez aussi appeler cela comme theArray.prototype.forEach (...);

prototype: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b

Vous pouvez également modifier un tableau comme ceci:

for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}
4
Nouman Dilshad

si vous voulez parcourir un tableau d'objets avec une fonction de flèche:

let arr=[{name:'john',age:50},{name:'clark',age:19},{name:'mohan',age:26}];

arr.forEach((person)=>{
  console.log('i am '+person.name+' and i am '+person.age+ ' old');
})
3
subhashish negi

Résumé:

Lors d'une itération sur un tableau, nous pouvons souvent vouloir atteindre l'un des objectifs suivants:

  1. Nous voulons parcourir le tableau et créer un nouveau tableau:

    Array.prototype.map 

  2. Nous voulons parcourir le tableau sans créer de nouveau tableau:

    Array.prototype.forEach 

    for..of boucle

Dans JS, il existe de nombreuses façons d’atteindre ces deux objectifs. Cependant, certains sont plus conventionnels que d'autres. Ci-dessous, vous trouverez quelques méthodes couramment utilisées (la plus conventionnelle) pour effectuer une itération de tableau en javascript.

Création d'un nouveau tableau: Map

map() est une fonction située sur Array.prototype qui peut transformer chaque élément d'un tableau puis retourne un new array. map() prend en argument une fonction de rappel et fonctionne de la manière suivante:

let arr = [1, 2, 3, 4, 5];

let newArr = arr.map((element, index, array) => {
  return element * 2;
})

console.log(arr);
console.log(newArr);

Le rappel que nous avons transmis à map() en tant qu'argument est exécuté pour chaque élément. Ensuite, un tableau est renvoyé qui a la même longueur que le tableau d'origine. Dans ce nouvel élément de tableau, la fonction de rappel transmise sous forme d'argument à map() est transformée.

La différence distincte entre map et un autre mécanisme de boucle tel que forEach et une boucle for..of réside dans le fait quemap est renvoyé sous la forme d'un nouveau tableau et laisse le tableau ancien intact (sauf si vous le manipulez explicitement avec la méthode splice

Notez également que le rappel de la fonction map fournit comme deuxième argument le numéro d'index de l'itération en cours. De plus, le troisième argument fournit le tableau sur lequel map a été appelé. Parfois, ces propriétés peuvent être très utiles.

Boucle avec forEach

forEach est une fonction située sur Array.prototype qui prend une fonction de rappel en tant qu'argument. Il exécute ensuite cette fonction de rappel pour chaque élément du tableau. Contrairement à la fonction map(), la fonction forEach ne renvoie rien (undefined). Par exemple:

let arr = [1, 2, 3, 4, 5];

arr.forEach((element, index, array) => {

  console.log(element * 2);

  if (index === 4) {
    console.log(array)
  }
  // index, and oldArray are provided as 2nd and 3th argument by the callback

})

console.log(arr);

Tout comme la fonction map, le rappel forEach fournit comme deuxième argument le numéro d'index de l'itération en cours. Le troisième argument fournit également le tableau sur lequel forEach a été appelé. 

Boucle à travers des éléments en utilisant for..of

La boucle for..of parcourt tous les éléments d'un tableau (ou tout autre objet itérable). Cela fonctionne de la manière suivante:

let arr = [1, 2, 3, 4, 5];

for(let element of arr) {
  console.log(element * 2);
}

Dans l'exemple ci-dessus, element représente un élément de tableau et arr est le tableau que nous voulons boucler. Non pas que le nom element soit arbitraire et nous aurions pu choisir un autre nom comme 'el' ou quelque chose de plus déclaratif lorsque cela est applicable. 

Ne confondez pas la boucle for..in avec la boucle for..of. for..in parcourt toutes les propriétés énumérables du tableau alors que la boucle for..of parcourt uniquement les éléments du tableau. Par exemple:

let arr = [1, 2, 3, 4, 5];

arr.foo = 'foo';

for(let element of arr) {
  console.log(element);
}

for(let element in arr) {
  console.log(element);
}

2

Si vous avez un tableau énorme, utilisez iterators pour gagner en efficacité. Les itérateurs sont une propriété de certaines collections JavaScript (comme Map , Set , String , Array ). Même, for..of utilise iterator sous le capot.

Les itérateurs améliorent l'efficacité en vous permettant de consommer les éléments d'une liste, l'un après l'autre, comme s'il s'agissait d'un flux. Ce qui rend un itérateur spécial, c'est la façon dont il parcourt une collection. Les autres boucles doivent charger toute la collection à l’avance pour pouvoir être parcourues, alors qu’un itérateur n’a besoin que de connaître la position actuelle dans la collection. 

Vous accédez à l’élément en cours en appelant la méthode next de l’itérateur. La méthode suivante renverra la value de l'élément actuel et une boolean pour indiquer le moment où vous avez atteint la fin de la collection. Voici un exemple de création d'un itérateur à partir d'un tableau. 

Transformez votre tableau régulier en itérateur à l’aide de values() comme ceci: 

    const myArr = [2,3,4]

let it = myArr.values();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Vous pouvez également transformer votre tableau régulier en itérateur à l’aide de Symbol.iterator comme ceci: 

const myArr = [2,3,4]

let it = myArr[Symbol.iterator]();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Vous pouvez également transformer votre array régulière en un iterator comme ceci: 

let myArr = [8, 10, 12];

function makeIterator(array) {
    var nextIndex = 0;
    
    return {
       next: function() {
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
};

var it = makeIterator(myArr);

console.log(it.next().value);   // {value: 8, done: false}
console.log(it.next().value);   // {value: 10, done: false}
console.log(it.next().value);   // {value: 12, done: false}
console.log(it.next().value);   // {value: undefined, done: true}

REMARQUE

  • Les itérateurs sont épuisables par nature. 
  • Les objets ne sont pas iterable par défaut. Utilisez for..in dans ce cas car au lieu de valeurs, cela fonctionne avec des clés.

Vous pouvez en savoir plus sur iteration protocolici

1
BlackBeard
var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})
1
John

// Looping through arrays using foreach  ES6 way

var data = new Array(1,2,3,4,5);
data.forEach((val,index) => {
    console.log("index :",index); // index
	console.log("value :", val); // value
});

0
arul prince

Vous pouvez utiliser forEach () API (fournie par Javascript) qui accepte une fonction en tant que rappel et s'exécute une fois pour chaque élément présent dans le tableau.

https://fullstackgeek.blogspot.com/2019/01/arrays-in-javascript-part-2.html

0
Ayush Jain

Je viens de python et j'ai trouvé cela beaucoup plus clair.
theArray étant le tableau, instance étant l'élément du tableau

for(let instance of theArray)
{
    console.log("The instance",instance);
}

ou

for( instance in theArray)
{
  console.log("The instance",instance);
}

comparer aux:

theArray.forEach(function(instance) {
    console.log(instance);
});

mais à la fin de la journée, les deux font la même chose

0
Peko Chan

Si vous voulez conserver votre code de manière fonctionnelle, utilisez map:

theArray.map(instance => do_something);

De cette façon, vous générerez un nouveau tableau pour les opérations futures et vous éviterez tout effet secondaire indésirable.

0
alejoko

Si vous voulez utiliser forEach(), cela ressemblera à - 

theArray.forEach ( element => {
    console.log(element);
});

Si vous voulez utiliser for(), cela ressemblera à - 

for(let idx = 0; idx < theArray.length; idx++){
    let element = theArray[idx];
    console.log(element);
}
0
Harunur Rashid