TypeScript per ... di con indice / chiave?


146

Come descritto qui TypeScript introduce un ciclo foreach:

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

Ma non c'è alcun indice / chiave? Mi aspetterei qualcosa del tipo:

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

Risposte:


274

.forEach ha già questa capacità:

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

Ma se vuoi le abilità di for...of, allora puoi mapl'array per l'indice e il valore:

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

È un po 'lungo, quindi potrebbe essere utile metterlo in una funzione riutilizzabile:

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

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

Versione Iterable

Funzionerà quando si sceglie ES3 o ES5 se si compila con l' --downlevelIterationopzione del compilatore.

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 +

Se sei in grado di indirizzare gli ambienti ES6 +, puoi utilizzare il .entries()metodo come indicato nella risposta di Arnavion .


Ma TypeScript compila "per ... di" in un semplice "per" che ha un indice var _i. Quindi sarebbe facile per gli sviluppatori TypeScript lasciarci usare questo _i. Vedi esempio di parco giochi: bit.ly/1R9SfBR
Mick

2
@Mick dipende dal bersaglio. Quando si traspila in ES6 non lo fa. Il motivo di quel codice aggiuntivo durante la trasplicazione è solo per far funzionare il codice ES6 nelle versioni precedenti.
David Sherret,

3
Come puoi fare una pausa; in quello per ogni?
João Silva,


@ JoãoSilva è possibile utilizzare Array.some()e restituire false all'iterazione che si desidera interrompere. Non è così chiaro o carino come un breakma farebbe il lavoro. Personalmente non mi piace, probabilmente riscriverei l'iterazione in qualche altro modo :) vedi stackoverflow.com/questions/2641347/…
Neek


35

"Old school javascript" in soccorso (per chi non ha familiarità / ama la programmazione funzionale)

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

2
In realtà preferisco questa risposta al meglio. Nessun utilizzo di metodi extra solo per generare un indice per ciascun elemento.
Bluegrounds

Grazie mille muyuchh! Non lo sapevamo :)
TSR

14

È possibile utilizzare l' operatore for..in TypeScript per accedere all'indice quando si ha a che fare con le raccolte.

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

Produzione:

 0: 7
 1: 8
 2: 9

Vedi la demo


Tenere presente che "i" è una stringa non un int con ciclo for..in. L'esecuzione dell'operazione aritmetica con "i" comporterà la concatenazione di stringhe. (i + 1) sarà uguale a "01", ad esempio quando i = 0
Stéphane

for..inpuò anche darti più di quello che ti aspettavi in ​​quanto include anche tutte le funzioni dichiarate su un oggetto. Ad esempio:for (var prop in window.document) { console.log(prop); }
Ken Lyon,

5

O un'altra soluzione vecchia scuola:

var someArray = [9, 2, 5];
let i = 0;
for (var item of someArray) {
    console.log(item); // 9,2,5
    i++;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.