¿TypeScript para ... de con índice / clave?


146

Como se describe aquí, TypeScript presenta un bucle foreach:

var someArray = [9, 2, 5];
for (var item of someArray) {
    console.log(item); // 9,2,5
}

¿Pero no hay ningún índice / clave? Esperaría algo como:

for (var item, key of someArray) { ... }

Respuestas:


274

.forEach ya tiene esta habilidad:

const someArray = [9, 2, 5];
someArray.forEach((value, index) => {
    console.log(index); // 0, 1, 2
    console.log(value); // 9, 2, 5
});

Pero si desea las habilidades de for...of, entonces puede mapcolocar la matriz en el índice y el valor:

for (const { index, value } of someArray.map((value, index) => ({ index, value }))) {
    console.log(index); // 0, 1, 2
    console.log(value); // 9, 2, 5
}

Eso es un poco largo, por lo que puede ser útil ponerlo en una función reutilizable:

function toEntries<T>(a: T[]) {
    return a.map((value, index) => [index, value] as const);
}

for (const [index, value] of toEntries(someArray)) {
    // ..etc..
}

Versión Iterable

Esto funcionará cuando apunte a ES3 o ES5 si compila con la --downlevelIterationopción del compilador.

function* toEntries<T>(values: T[] | IterableIterator<T>) {
    let index = 0;
    for (const value of values) {
        yield [index, value] as const;
        index++;
    }
}

Array.prototype.entries () - ES6 +

Si puede apuntar a entornos ES6 +, puede usar el .entries()método como se describe en la respuesta de Arnavion .


Pero TypeScript compila "para ... de" a un simple "para" que tiene un índice var _i. Por lo tanto, sería fácil para los desarrolladores de TypeScript dejarnos usar este _i. Ver ejemplo de patio de juegos: bit.ly/1R9SfBR
Mick

2
@Mick depende del objetivo. Al transpirar a ES6 no hace eso. La razón de ese código adicional al transpilar es solo para que el código ES6 funcione en versiones anteriores.
David Sherret

3
¿Cómo puedes hacer un descanso? en eso para cada uno?
João Silva el


@ JoãoSilva puede usar Array.some()y devolver falso en la iteración que desea detener. No es tan claro o bonito como un breakpero podría hacer el trabajo. Personalmente no me gusta, probablemente volvería a escribir la iteración de alguna otra manera :) ver stackoverflow.com/questions/2641347/…
Neek


35

"Old school javascript" al rescate (para aquellos que no están familiarizados / aman la programación funcional)

for (let i = 0; i < someArray.length ; i++) {
  let item = someArray[i];
}

2
De hecho, prefiero esta respuesta la mejor. No utilizar métodos adicionales solo para generar un índice para cada elemento.
bluegrounds

Gracias muuuuuuuuuuuuuuuu! No sabíamos esto :)
TSR

14

Puede usar el operador for..in TypeScript para acceder al índice cuando trabaje con colecciones.

var test = [7,8,9];
for (var i in test) {
   console.log(i + ': ' + test[i]);
} 

Salida:

 0: 7
 1: 8
 2: 9

Ver demo


Tenga en cuenta que "i" es una cadena no un int con for..in loop. Realizar una operación aritmética con "i" dará como resultado la concatenación de cadenas. (i + 1) será igual a "01", por ejemplo, cuando i = 0
Stéphane

for..intambién puede darle más de lo que esperaba, ya que también incluye todas las funciones declaradas en un objeto. Por ejemplo:for (var prop in window.document) { console.log(prop); }
Ken Lyon

5

O otra solución de la vieja escuela:

var someArray = [9, 2, 5];
let i = 0;
for (var item of someArray) {
    console.log(item); // 9,2,5
    i++;
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.