TypeScript pour… ou avec index / clé?


146

Comme décrit ici, TypeScript introduit une boucle foreach:

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

Mais n'y a-t-il pas d'index / clé? Je m'attendrais à quelque chose comme:

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

Réponses:


274

.forEach a déjà cette capacité:

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

Mais si vous voulez les capacités de for...of, alors vous pouvez maple tableau à l'index et à la valeur:

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

C'est un peu long, il peut donc être utile de le mettre dans une fonction réutilisable:

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

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

Version itérable

Cela fonctionnera lorsque vous ciblez ES3 ou ES5 si vous compilez avec l' --downlevelIterationoption du compilateur.

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 vous pouvez cibler les environnements ES6 +, vous pouvez utiliser la .entries()méthode décrite dans la réponse d'Arnavion .


Mais TypeScript compile "for ... of" en un simple "for" qui a un index var _i. Il serait donc facile pour les développeurs TypeScript de nous laisser utiliser ce _i. Voir l'exemple de l'aire de jeux: bit.ly/1R9SfBR
Mick

2
@Mick cela dépend de la cible. Lors du transpilage vers ES6, il ne le fait pas. La raison de ce code supplémentaire lors de la transpilation est uniquement de faire fonctionner le code ES6 dans les versions précédentes.
David Sherret

3
Comment pouvez-vous faire une pause; dans ce forEach?
João Silva


@ JoãoSilva vous pouvez utiliser Array.some()et renvoyer false à l'itération que vous souhaitez arrêter. Ce n'est pas aussi clair ou joli qu'un, breakmais cela ferait le travail. Personnellement, je n'aime pas ça, je réécrirais probablement l'itération d'une autre manière :) voir stackoverflow.com/questions/2641347/…
Neek


35

"Old school javascript" à la rescousse (pour ceux qui ne sont pas familiers / amoureux de la programmation fonctionnelle)

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

2
Je préfère en fait cette réponse la meilleure. Pas d'utilisation de méthodes supplémentaires juste pour générer un index pour chaque élément.
bluegrounds

Merci veryyyy muuuchh! Nous ne savions pas cela :)
TSR

14

Vous pouvez utiliser l' opérateur TypeScript for..in pour accéder à l'index lorsque vous traitez des collections.

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

Production:

 0: 7
 1: 8
 2: 9

Voir la démo


Sachez que "i" est une chaîne et non un int avec une boucle for..in. L'exécution d'une opération arithmétique avec "i" entraînera une concaténation de chaînes. (i + 1) sera égal à "01" par exemple quand i = 0
Stéphane

for..inpeut également vous donner plus que ce à quoi vous vous attendiez car il inclut également toutes les fonctions déclarées sur un objet. Par exemple:for (var prop in window.document) { console.log(prop); }
Ken Lyon

5

Ou une autre solution à l'ancienne:

var someArray = [9, 2, 5];
let i = 0;
for (var item of someArray) {
    console.log(item); // 9,2,5
    i++;
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.