Hot para obtener el contador/índice de bucle usando la sintaxis for…of en JavaScript

5 minutos de lectura

avatar de usuario de hobbes3
hobbes3

Precaución:

la pregunta todavía se aplica a for…of bucles.> No usar for…in para iterar sobre un Formaciónutilícelo para iterar sobre el propiedades de un objeto Dicho esto, esto


Entiendo que lo básico for…in La sintaxis en JavaScript se ve así:

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

Pero, ¿cómo obtengo el bucle? contador/índice?

Sé que probablemente podría hacer algo como:

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

O incluso el buen viejo:

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

Pero prefiero usar el más simple. for-in círculo. Creo que se ven mejor y tienen más sentido.

¿Hay una manera más simple o más elegante?


En Python es fácil:

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

  • No use for…in para arreglos. Y de todos modos, itera sobre los nombres de las propiedades, no sobre los valores de las propiedades.

    – Félix Kling

    16 de abril de 2012 a las 18:49


  • Es una matriz, no un objeto, ¿verdad? Asi que, alert(obj)?

    – genérico

    16 de abril de 2012 a las 18:49


Avatar de usuario de Ry-
Ry-

for…in itera sobre nombres de propiedad, no valores, y lo hace en un orden no especificado (sí, incluso después de ES6). No debe usarlo para iterar sobre matrices. Para ellos, hay ES5 forEach método que pasa tanto el valor como el índice a la función que le das:

var myArray = [123, 15, 187, 32];

myArray.forEach(function (value, i) {
    console.log('%d: %s', i, value);
});

// Outputs:
// 0: 123
// 1: 15
// 2: 187
// 3: 32

O ES6 Array.prototype.entriesque ahora es compatible con las versiones actuales del navegador:

for (const [i, value] of myArray.entries()) {
    console.log('%d: %s', i, value);
}

Para iterables en general (donde usaría un for…of bucle en lugar de un for…in), no hay nada incorporado, sin embargo:

function* enumerate(iterable) {
    let i = 0;

    for (const x of iterable) {
        yield [i, x];
        i++;
    }
}

for (const [i, obj] of enumerate(myArray)) {
    console.log(i, obj);
}

manifestación

Si en realidad quisiste decir for…in – propiedades de enumeración – necesitaría un contador adicional. Object.keys(obj).forEach podría funcionar, pero solo incluye propio propiedades; for…in incluye propiedades enumerables en cualquier parte de la cadena de prototipos.

  • En realidad, obj será el índice de la matriz, pero no hay garantía de que esté en orden y que no incluya otros nombres de propiedad.

    – Félix Kling

    16 de abril de 2012 a las 18:52

  • @quantumpotato: letson vars con ámbito de bloque. consts son inmutables.

    – Ry-

    14 de diciembre de 2016 a las 7:50

  • pregunta estúpida, pero ¿qué significan realmente %d y %s, o podrían ser cualquier letra que yo quiera que sean?

    – klewis

    7 de agosto de 2019 a las 13:24


  • @klewis: %d da formato a un entero y %s formatea una cadena. están basados ​​en imprimir. Una especificación está en progreso en console.spec.whatwg.org/#formatter.

    – Ry-

    7 de agosto de 2019 a las 13:39

  • La desventaja de forEach es eso await inside tiene como alcance el parámetro de función, no el alcance externo. Entonces, si desea esperar dentro del ciclo, probablemente desee usar .entries().

    – usuario1338062

    12 de junio de 2021 a las 7:33

avatar de usuario de rushUp
apresurarse

En ES6, es bueno usar un for... of círculo. Puede obtener el índice en for... of como esto

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

Tenga en cuenta que Array.entries() devoluciones un iterador, que es lo que le permite funcionar en el bucle for-of; no confundas esto con Objeto.entradas()que devuelve un formación de pares clave-valor.

  • Creo que esta solución es mejor que forEach one… Utiliza la sintaxis de bucle nomral for…of, y no tiene que usar una función separada. En otras palabras, es sintácticamente mejor. El OP parece haber querido esto.

    – u8y7541

    29 de julio de 2017 a las 17:31

  • entries() está devolviendo un objeto vacío: {}. ¿Alguna idea de por qué sería eso? Mi array es una matriz de objetos.

    – Josué Pinter

    30 de julio de 2017 a las 22:57

  • @JoshuaPinter prueba Object.entries(array) en vez de array.entries()

    – tonyg

    29/09/2017 a las 15:50

  • Se supone que debe hacer eso, Joshua: el objeto es un iterador, un objeto con un next() método que devolverá las entradas subsiguientes en la matriz cada vez que se llame. No hay datos (visibles) en él; obtienes los datos en el objeto subyacente llamando next(), que for-of hace entre bastidores. cc @tonyg

    – Shog9

    29/09/2017 a las 16:30

  • También esto permite await trabajar en secuencia, mientras que forEach no es.

    – geodésico

    6 de diciembre de 2020 a las 13:08

Avatar de usuario de Sanjay Shr
Sanjay Shr

Qué tal esto

let numbers = [1,2,3,4,5]
numbers.forEach((number, index) => console.log(`${index}:${number}`))

Dónde array.forEach este método tiene un index parámetro que es el índice del elemento actual que se procesa en la matriz.

  • La respuesta elegida se publicó 6 años antes de esta y ya tiene lo mismo …

    – Dios

    16 abr 2019 a las 20:02

  • Foreach no es bueno para la optimización, ya que break no está disponible.

    – smartworld-dm

    30 de enero de 2020 a las 9:47

  • @smartworld-dm Estoy de acuerdo con esto, pero existe la declaración de devolución simple.

    – sld

    24 de agosto a las 23:08

Solución para colecciones de matrices pequeñas:

for (var obj in arr) {
    var i = Object.keys(arr).indexOf(obj);
}

Arr – ARREGLO,
objeto – CLAVE del elemento actual,
i – CONTADOR/ÍNDICE

Aviso: Método llaves() no está disponible para la versión IE polirelleno código.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

Avatar de usuario de Bergi
Bergi

Los bucles for-in iteran sobre las propiedades de un objeto. No los use para arreglos, incluso si a veces funcionan.

Las propiedades de los objetos no tienen índice, son todas iguales y no es necesario ejecutarlas en un orden determinado. Si desea contar propiedades, deberá configurar el contador adicional (como lo hizo en su primer ejemplo).

bucle sobre una matriz:

var a = [];
for (var i=0; i<a.length; i++) {
    i // is the index
    a[i] // is the item
}

bucle sobre un objeto:

var o = {};
for (var prop in o) {
    prop // is the property name
    o[prop] // is the property value - the item
}

  • Nunca lo haces (var i=0; i<a.length; i++) al igual que los recursos desperdiciados. Usar (var i=0, var len = a.length; i<len; i++)

    – Félix Sanz

    29 de agosto de 2014 a las 1:59


  • @FelixSanz: ¿Desperdiciar recursos? De ninguna manera. Esa es una microoptimización prematura que casi nunca es necesaria, y var i=0; i<a.length; i++) es el patrón de bucle estándar que está optimizado por cada motor javascript decente de todos modos.

    – Bergi

    29 de agosto de 2014 a las 10:57


  • @FelixSanz: Sí, y var i=0; i<a.length; i++ es la mejor práctica.

    – Bergi

    30 de agosto de 2014 a las 11:01

  • BESO. Si escribe bucles donde realmente necesita esto, está haciendo algo mal o tiene un mejor argumento para su necesidad que la “mejor práctica”. Sí, es una práctica estándar, pero no para la optimización genérica del rendimiento, sino solo para la microoptimización.

    – Bergi

    1 de septiembre de 2014 a las 12:02

  • KISS se aplica en todas partes. Optimización prematura es una antipráctica.

    – Bergi

    1 de septiembre de 2014 a las 15:01

Avatar de usuario de Robert Messerle
Roberto Messerle

Como han dicho otros, no debería usar for..in para iterar sobre una matriz.

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

Si desea una sintaxis más limpia, puede usar forEach:

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

Si desea utilizar este método, asegúrese de incluir el shim ES5 para agregar soporte para navegadores más antiguos.

  • Nunca lo haces (var i=0; i<a.length; i++) al igual que los recursos desperdiciados. Usar (var i=0, var len = a.length; i<len; i++)

    – Félix Sanz

    29 de agosto de 2014 a las 1:59


  • @FelixSanz: ¿Desperdiciar recursos? De ninguna manera. Esa es una microoptimización prematura que casi nunca es necesaria, y var i=0; i<a.length; i++) es el patrón de bucle estándar que está optimizado por cada motor javascript decente de todos modos.

    – Bergi

    29 de agosto de 2014 a las 10:57


  • @FelixSanz: Sí, y var i=0; i<a.length; i++ es la mejor práctica.

    – Bergi

    30 de agosto de 2014 a las 11:01

  • BESO. Si escribe bucles donde realmente necesita esto, está haciendo algo mal o tiene un mejor argumento para su necesidad que la “mejor práctica”. Sí, es una práctica estándar, pero no para la optimización genérica del rendimiento, sino solo para la microoptimización.

    – Bergi

    1 de septiembre de 2014 a las 12:02

  • KISS se aplica en todas partes. Optimización prematura es una antipráctica.

    – Bergi

    1 de septiembre de 2014 a las 15:01

Avatar de usuario de Renish Gotecha
Renish Gotecha

Respuesta dada por rushUp Es correcta pero esto será más conveniente

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

  • || [] es innecesario y nunca se utilizará; array.entries() siempre es veraz.

    – Ry-

    31 oct 2020 a las 0:20

  • [index, val] nunca me funciona, dice “indefinido”

    – Barbz_YHOOL

    21 mayo 2021 a las 19:44

  • ¿Puedes compartir tu matriz?

    – Renish Gotecha

    22 de mayo de 2021 a las 12:32

¿Ha sido útil esta solución?