TypeScript für… von mit Index / Schlüssel?

144

Wie hier beschrieben , führt TypeScript eine foreach-Schleife ein:

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

Aber gibt es keinen Index / Schlüssel? Ich würde so etwas erwarten wie:

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

Antworten:

273

.forEach hat bereits diese Fähigkeit:

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

Aber wenn Sie die Fähigkeiten von wollen for...of, dann können Sie mapdas Array zum Index und Wert:

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

Das ist etwas lang, daher kann es hilfreich sein, es in eine wiederverwendbare Funktion zu versetzen:

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

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

Iterable Version

Dies funktioniert beim Targeting von ES3 oder ES5, wenn Sie mit der --downlevelIterationCompileroption kompilieren .

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 +

Wenn Sie in der Lage sind, auf ES6 + -Umgebungen abzuzielen, können Sie .entries()die in Arnavions Antwort beschriebene Methode verwenden .

David Sherret
quelle
Aber TypeScript kompiliert "für ... von" zu einem einfachen "für", das einen Index var _i hat. Daher wäre es für TypeScript-Entwickler einfach, dieses _i zu verwenden. Siehe Spielplatzbeispiel: bit.ly/1R9SfBR
Mick
2
@ Mick es kommt auf das Ziel an. Beim Transpilieren auf ES6 funktioniert das nicht. Der Grund für diesen zusätzlichen Code beim Transpilieren besteht nur darin, dass der ES6-Code in früheren Versionen funktioniert.
David Sherret
3
Wie kannst du eine Pause machen? in diesem für jeden?
João Silva
Auch eine gute Antwort stackoverflow.com/questions/34348937/…
Christopher Grigg
@ JoãoSilva Sie können Array.some()false bei der Iteration verwenden und zurückgeben, die Sie stoppen möchten. Es ist bei weitem nicht so klar oder hübsch wie ein, breakaber es würde die Arbeit erledigen. Persönlich mag ich es nicht, ich würde die Iteration wahrscheinlich auf eine andere Weise neu schreiben :) siehe stackoverflow.com/questions/2641347/…
Neek
35

"Old School Javascript" zur Rettung (für diejenigen, die nicht vertraut sind / die funktionale Programmierung lieben)

for (let i = 0; i < someArray.length ; i++) {
  let item = someArray[i];
}
Sylvain
quelle
2
Ich bevorzuge diese Antwort eigentlich am besten. Keine Verwendung zusätzlicher Methoden, nur um einen Index für jedes Element zu generieren.
Bluegrounds
Vielen Dank, dass Sie sehr yyy muuuchh! Wir wussten das nicht :)
TSR
14

Sie können den for..in TypeScript-Operator verwenden, um beim Umgang mit Sammlungen auf den Index zuzugreifen.

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

Ausgabe:

 0: 7
 1: 8
 2: 9

Siehe Demo

Karanvir Kang
quelle
Beachten Sie, dass "i" eine Zeichenfolge ist, die kein int mit for..in-Schleife ist. Das Ausführen einer arithmetischen Operation mit "i" führt zur Verkettung von Zeichenfolgen. (i + 1) ist gleich "01", zum Beispiel wenn i = 0
Stéphane
for..inkann Ihnen auch mehr geben, als Sie erwartet hatten, da es auch alle Funktionen enthält, die für ein Objekt deklariert wurden. Zum Beispiel:for (var prop in window.document) { console.log(prop); }
Ken Lyon
5

Oder eine andere Lösung der alten Schule:

var someArray = [9, 2, 5];
let i = 0;
for (var item of someArray) {
    console.log(item); // 9,2,5
    i++;
}
Galdor
quelle