696 votes

Obtenir un compteur/index de boucle en utilisant la syntaxe for of en JavaScript

Attention :

La question s'applique toujours à for…of n'utilisez pas for…in pour itérer sur un Array et l'utiliser pour itérer sur le propriétés d'un objet. Cela dit, cette


Je comprends que la base for…in en JavaScript ressemble à ceci :

for (var obj in myArray) {
    // ...
}

Mais comment faire pour que la boucle compteur/index ?

Je sais que je pourrais probablement faire quelque chose comme :

var i = 0;
for (var obj in myArray) {
    alert(i)
    i++
}

Ou même le bon vieux :

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

Mais je préfère utiliser le plus simple for-in boucle. Je pense qu'ils sont plus beaux et plus logiques.

Existe-t-il un moyen plus simple ou plus élégant ?


En Python, c'est facile :

for i, obj in enumerate(myArray):
    print i

11voto

Robert Messerle Points 1994

Comme d'autres l'ont dit, vous ne devriez pas utiliser for..in pour itérer sur un tableau.

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

Si vous voulez une syntaxe plus propre, vous pouvez utiliser forEach :

myArray.forEach( function ( val, i ) { ... } );

Si vous souhaitez utiliser cette méthode, assurez-vous d'inclure la shim ES5 pour ajouter la prise en charge des navigateurs plus anciens.

7voto

Renish Gotecha Points 51

La réponse donnée par RushUp est correcte mais ceci sera plus pratique.

for (let [index, val] of array.entries() || []) {
   // your code goes here    
}

2voto

Rivenfall Points 947

Voici une fonction eachWithIndex qui fonctionne avec tout ce qui est itérable.

Vous pouvez également écrire une fonction similaire eachWithKey qui fonctionne avec des objets utilisant for...in .

// example generator (returns an iterator that can only be iterated once)
function* eachFromTo(start, end) { for (let i = start; i <= end; i++) yield i }

// convers an iterable to an array (potential infinite loop)
function eachToArray(iterable) {
    const result = []
    for (const val of iterable) result.push(val)
    return result
}

// yields every value and index of an iterable (array, generator, ...)
function* eachWithIndex(iterable) {
    const shared = new Array(2)
    shared[1] = 0
    for (shared[0] of iterable) {
        yield shared
        shared[1]++
    }
}

console.log('iterate values and indexes from a generator')
for (const [val, i] of eachWithIndex(eachFromTo(10, 13))) console.log(val, i)

console.log('create an array')
const anArray = eachToArray(eachFromTo(10, 13))
console.log(anArray)

console.log('iterate values and indexes from an array')
for (const [val, i] of eachWithIndex(anArray)) console.log(val, i)

La bonne chose avec les générateurs est qu'ils sont paresseux et peuvent prendre le résultat d'un autre générateur comme argument.

2voto

akurtser Points 464

C'est ma version d'un itérateur composite qui produit un index et toute valeur de fonction génératrice passée, avec un exemple de recherche primaire (lente) :

const eachWithIndex = (iterable) => {
  return {
    *[Symbol.iterator]() {
      let i = 0
      for(let val of iteratable) {
        i++
          yield [i, val]
      }
    }
  }

}

const isPrime = (n) => {
  for (i = 2; i < Math.floor(Math.sqrt(n) + 1); i++) {
    if (n % i == 0) {
      return false
    }
  }
  return true
}

let primes = {
  *[Symbol.iterator]() {
    let candidate = 2
    while (true) {
      if (isPrime(candidate)) yield candidate
        candidate++
    }
  }
}

for (const [i, prime] of eachWithIndex(primes)) {
  console.log(i, prime)
  if (i === 100) break
}

2voto

Bursos Points 305

En plus des très bonnes réponses que tout le monde a postées, je voudrais ajouter que la solution la plus performante est l'ES6. entries . Cela semble contraint pour beaucoup de développeurs ici, donc j'ai créé ce perf benchamrk .

enter image description here

C'est ~6 fois plus rapide. Principalement parce qu'elle n'a pas besoin : a) d'accéder au tableau plus d'une fois et, b) de convertir l'index.

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