Zugriff auf den ES6-Array-Elementindex innerhalb der for-of-Schleife


227

Wir können mit einer for-of-Schleife auf Array-Elemente zugreifen:

for (const j of [1, 2, 3, 4, 5]) {
  console.log(j);
}

Wie kann ich diesen Code ändern, um auch auf den aktuellen Index zuzugreifen? Ich möchte dies mit der For-of-Syntax erreichen, weder mit forEach noch mit for-in.

Antworten:


348

Verwendung Array.prototype.keys:

for (const index of [1, 2, 3, 4, 5].keys()) {
  console.log(index);
}

Wenn Sie zugreifen möchten sowohl den Schlüssel und den Wert, können Sie Array.prototype.entries()mit Destrukturierung :

for (const [index, value] of [1, 2, 3, 4, 5].entries()) {
  console.log(index, value);
}


64
Falls jemand fragt, testete ich for-ofmit .entries()und es ist doppelt so langsam im Vergleich zu .forEach(). jsperf.com/for-of-vs-foreach-with-index

1
@ K48 schön zu wissen, verwenden Sie "umgekehrte for-Schleife", wenn Sie die schnellste in es haben wollen: unglaubliche-web.com/blog/…
nimo23

3
Leider muss ich aus einer verschachtelten Schleife heraus nachgeben. ForEach kann nicht verwendet werden, da die Funktion Bereichsprobleme für das yieldSchlüsselwort verursacht. Aber ich brauche Zugriff auf den Index für meinen Anwendungsfall, also ... ;;es ist eine grundlegende alte Schleife, denke ich.
Kyle Baker

2
@KyleBaker Und was ist los mit einer For-of-Schleife .entires()?
Michał Perłakowski

1
Anstelle der umgekehrten Schleife können Sie die Länge jsperf.com/reverse-loop-vs-cache zwischenspeichern . For-of nützlich für die iterierbare Verarbeitung, wenn Sie Streams verarbeiten können, ohne große Arrays im RAM zu erstellen. Die Schleifengeschwindigkeit wäre kein Engpass, da in solchen Fällen eine E / A-Latenz auftritt.
x'ES

289

Array#entries Gibt den Index und den Wert zurück, wenn Sie beide benötigen:

for (let [index, value] of array.entries()) {

}

3
Mit TypeScript: 'TS2495: Type IterableIterator ist kein Array-Typ oder String-Typ'. Scheint so, als ob dies gelöst wird: github.com/Microsoft/TypeScript/pull/12346
Johannes

2
Auch Internet Explorer wird nicht unterstützt.
Sammi

1
Nicht nett. Wirft einen Fehler, z. B. mit document.styleSheets[0].cssRules.entries()oder sogar document.styleSheets.entries()und wahrscheinlich mit vielen anderen iterierbaren DOM-Strukturen. Muss noch _.forEach()vonlodash
Steven Pribilinskiy

2
@Steven: Wenn Sie den Index nicht benötigen, können Sie dies einfach tun for (var value of document.styleSheets) {}. Wenn Sie den Index benötigen, können Sie den Wert zuerst über Array.from: in ein Array konvertieren for (let [index, value] of Array.from(document.styleSheets)) {}.
Felix Kling

1
Das ist schön! Array.fromist FTW
Steven Pribilinskiy

28

In dieser Welt auffälliger neuer nativer Funktionen vergessen wir manchmal die Grundlagen.

for (let i = 0; i < arr.length; i++) {
    console.log('index:', i, 'element:', arr[i]);
}

Sauber, effizient und Sie können immer noch breakdie Schleife. Bonus! Sie können auch am Ende beginnen und rückwärts gehen mit i--!

Zusätzlicher Hinweis: Wenn Sie den Wert häufig in der Schleife verwenden, möchten Sie möglicherweise const value = arr[i];oben in der Schleife eine einfache, lesbare Referenz erstellen.


1
Ja. Gut, klar und einfach. Oh, und so haben Sie eine super einfache Möglichkeit, auf den Schlüssel / Index des Arrays zuzugreifen.
Kombinieren Sie

2
Übrigens sollte die Bedingung so aussehen -> für (sei i = 0; i <arr.length; i ++) ohne das (-1), sonst wird nicht alle Elemente des Arrays durchlaufen.
Kombinieren Sie den

1
@Combine Guter Fang! Ich habe meine Antwort aktualisiert, um Ihre Notiz wiederzugeben.
Chris

4
Sie können immer noch breakein for-ofund for (let [index, value] of array.entries())ist viel einfacher zu lesen. Das Zurückgehen ist so einfach wie das Hinzufügen .reverse().
Nigel B. Peck

2
Ich denke, dies ist eine durchaus akzeptable Antwort auf diese Frage. Es wird niemals die akzeptierte Antwort sein, aber es hat ein paar Dutzend oder mehr Menschen geholfen, die nach dieser Frage gesucht haben. Dafür ist SO da.
Danoram

3

Im HTML / JS-Kontext können wir in modernen Browsern mit anderen iterierbaren Objekten als Arrays auch [Iterable] .entries () verwenden:

for(let [index, element] of document.querySelectorAll('div').entries()) {

    element.innerHTML = '#' + index

}

Ja, dies funktioniert, während andere oben von @Steven Pribilinskiy erwähnte andere DOM-Methoden Objekte zurückgeben, für die keine entriesMethode vorhanden ist.
Matanster

3

In einer for..ofSchleife können wir dies über erreichen array.entries(). array.entriesGibt ein neues Array-Iteratorobjekt zurück. Ein Iteratorobjekt kann von einem iterierbaren Objekt aus auf Elemente zugreifen, während es seine aktuelle Position innerhalb dieser Sequenz verfolgt.

Beim next()Aufruf der Methode werden auf dem Iterator Schlüsselwertpaare generiert. In diesen Schlüsselwertpaaren ist der Array- Index der Schlüssel und das Array-Element der Wert.

let arr = ['a', 'b', 'c'];
let iterator = arr.entries();
console.log(iterator.next().value); // [0, 'a']
console.log(iterator.next().value); // [1, 'b']

Eine for..ofSchleife ist im Grunde ein Konstrukt, das eine Iterierbarkeit verbraucht und alle Elemente durchläuft (unter Verwendung eines Iterators unter der Haube). Wir können dies array.entries()folgendermaßen kombinieren :

array = ['a', 'b', 'c'];

for (let indexValue of array.entries()) {
  console.log(indexValue);
}


// we can use array destructuring to conveniently
// store the index and value in variables
for (let [index, value] of array.entries()) {
   console.log(index, value);
}


3

Sie können den Index auch selbst bearbeiten, wenn Sie den Index benötigen . Wenn Sie den Schlüssel benötigen, funktioniert er nicht .

let i = 0;
for (const item of iterableItems) {
  // do something with index
  console.log(i);

  i++;
}

0

Für diejenigen, die Objekte verwenden, die nicht Arrayoder sogar Array-ähnlich sind, können Sie einfach Ihre eigene iterierbare erstellen, sodass Sie sie weiterhin for offür Dinge verwenden können, localStoragedie wirklich nur Folgendes haben length:

function indexerator(length) {
    var output = new Object();
    var index = 0;
    output[Symbol.iterator] = function() {
        return {next:function() {
            return (index < length) ? {value:index++} : {done:true};
        }};
    };
    return output;
}

Dann füttere es einfach mit einer Nummer:

for (let index of indexerator(localStorage.length))
    console.log(localStorage.key(index))

0

es6 for...in

for(const index in [15, 64, 78]) {                        
    console.log(index);
}

5
Die Frage ist nach einer for...ofSchleife nicht afor...in
Abraham Hernandez

3
for...inist Teil der ursprünglichen ECMAScript-Spezifikation (dh "es1"). Beachten Sie außerdem, dass for...indies zum Durchlaufen von Objekteigenschaften gedacht ist. Es kann zwar über Arrays iterieren, dies jedoch möglicherweise nicht in der erwarteten Reihenfolge. Weitere
Boaz

0

Ein anderer Ansatz könnte Array.prototype.forEach()as verwenden

Array.from({
  length: 5
}, () => Math.floor(Math.random() * 5)).forEach((val, index) => {
  console.log(val, index)
})


-6
var fruits = ["apple","pear","peach"];
for (fruit of fruits) {
    console.log(fruits.indexOf(fruit));
    //it shows the index of every fruit from fruits
}

Die for-Schleife durchläuft das Array, während die indexof-Eigenschaft den Wert des Index annimmt, der mit dem Array übereinstimmt. PD Diese Methode hat einige Fehler mit Zahlen, also verwenden Sie Früchte


2
Dies dauert O (n ^ 2) Zeit.
Harry

3
In Fällen, in denen die Leistung nicht wichtig ist, werden immer noch nicht alle korrekten Indizes angezeigt, wenn doppelte Früchte vorhanden sind. Zum Beispiel sind für ["apple", "apple", "pear"]die angegebenen Indizes 0, 0, 2statt 0, 1, 2.
Trichoplax
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.