Vorsicht:
die Frage gilt weiterhin für
for…of
-Schleifen.> Verwenden Siefor…in
nicht zum Durchlaufen eines Arrays , sondern zum Durchlaufen von über den properties eines Objekts. Das sagte, das hier
Ich verstehe, dass die grundlegende for…in
-Syntax in JavaScript folgendermaßen aussieht:
for (var obj in myArray) {
// ...
}
Aber wie bekomme ich die Schleife counter/index?
var i = 0;
for (var obj in myArray) {
alert(i)
i++
}
for (var i = 0; 1 < myArray.length; i++) {
var obj = myArray[i]
alert(i)
}
Ich würde aber lieber die einfachere for-in
-Schleife verwenden. Ich finde, sie sehen besser aus und sind sinnvoller.
Gibt es einen einfacheren oder eleganteren Weg?
for i, obj in enumerate(myArray):
print i
_for…in
_ iteriert über Eigenschaftsnamen, nicht über Werte, und zwar in nicht angegebener Reihenfolge (ja, auch nach ES6). Sie sollten es nicht verwenden, um Arrays zu durchlaufen. Für sie gibt es die forEach
-Methode von ES5, die sowohl den Wert als auch den Index an die von Ihnen angegebene Funktion übergibt:
_var myArray = [123, 15, 187, 32];
myArray.forEach(function (value, i) {
console.log('%d: %s', i, value);
});
// Outputs:
// 0: 123
// 1: 15
// 2: 187
// 3: 32
_
Oder ES6s Array.prototype.entries
, das jetzt in allen aktuellen Browserversionen unterstützt wird:
_for (const [i, value] of myArray.entries()) {
console.log('%d: %s', i, value);
}
_
Für Iterables im Allgemeinen (bei denen Sie eine _for…of
_ -Schleife anstelle einer _for…in
_ verwenden würden) ist jedoch nichts integriert:
_function* enumerate(iterable) {
let i = 0;
for (const x of iterable) {
yield [i, x];
i++;
}
}
for (const [i, obj] of enumerate(myArray)) {
console.log(i, obj);
}
_
Wenn Sie tatsächlich _for…in
_ - Auflisten von Eigenschaften - gemeint hätten, bräuchten Sie einen zusätzlichen Leistungsindikator. Object.keys(obj).forEach
könnte funktionieren, enthält aber nur eigene Eigenschaften; _for…in
_ enthält überall in der Prototypenkette zahlreiche Eigenschaften.
In ES6 ist es ratsam, for - of loop . Zu verwenden. Sie können Index für so erhalten
for (let [index, val] of array.entries()) {
// your code goes here
}
Beachten Sie, dass Array.entries()
einen Iterator zurückgibt, wodurch er in der for-of-Schleife arbeiten kann. Verwechseln Sie dies nicht mit Object.entries () , das ein array von Schlüsselwertpaaren zurückgibt.
Lösung für kleine Array-Sammlungen:
for (var obj in arr) {
var i = Object.keys(arr).indexOf(obj);
}
arr - ARRAY, obj - TASTE des aktuellen Elements i - COUNTER/INDEX
Notice: Methode keys () ist für IE Version <9 nicht verfügbar. Sie sollten Polyfill code . https: //developer.mozilla) verwenden .org/de/docs/Web/JavaScript/Referenz/Globale_Objekte/Objekt/Schlüssel
For-in-Loops durchlaufen die Eigenschaften eines Objekts. Verwenden Sie sie nicht für Arrays, auch wenn sie manchmal funktionieren.
Objekteigenschaften haben dann keinen Index, sie sind alle gleich und müssen nicht in einer bestimmten Reihenfolge durchlaufen werden. Wenn Sie Eigenschaften zählen möchten, müssen Sie den zusätzlichen Zähler einrichten (wie in Ihrem ersten Beispiel).
schleife über ein Array:
var a = [];
for (var i=0; i<a.length; i++) {
i // is the index
a[i] // is the item
}
schleife über ein Objekt:
var o = {};
for (var prop in o) {
prop // is the property name
o[prop] // is the property value - the item
}
Wie wäre es damit
let numbers = [1,2,3,4,5]
numbers.forEach((number, index) => console.log(`${index}:${number}`))
Bei array.forEach
hat diese Methode einen index
-Parameter, der dem Index des aktuellen Elements entspricht, das im Array verarbeitet wird.
Wie andere schon gesagt haben, sollten Sie nicht for..in verwenden, um ein Array zu durchlaufen.
for ( var i = 0, len = myArray.length; i < len; i++ ) { ... }
Wenn Sie eine sauberere Syntax wünschen, können Sie forEach verwenden:
myArray.forEach( function ( val, i ) { ... } );
Wenn Sie diese Methode verwenden möchten, stellen Sie sicher, dass Sie das ES5-Shim mit einschließen, um Unterstützung für ältere Browser hinzuzufügen.
Hier ist eine Funktion eachWithIndex
, die mit allem funktioniert, das durchlaufen werden kann.
Sie könnten auch eine ähnliche Funktion eachWithKey
schreiben, die mit Objekten mit for...in
funktioniert.
// example generator (returns an iterator that can only be iterated once)
function* eachFromTo(start, end) { for (let i = start; i <= end; i++) yield i }
// convers an iterable to an array (potential infinite loop)
function eachToArray(iterable) {
const result = []
for (const val of iterable) result.Push(val)
return result
}
// yields every value and index of an iterable (array, generator, ...)
function* eachWithIndex(iterable) {
const shared = new Array(2)
shared[1] = 0
for (shared[0] of iterable) {
yield shared
shared[1]++
}
}
console.log('iterate values and indexes from a generator')
for (const [val, i] of eachWithIndex(eachFromTo(10, 13))) console.log(val, i)
console.log('create an array')
const anArray = eachToArray(eachFromTo(10, 13))
console.log(anArray)
console.log('iterate values and indexes from an array')
for (const [val, i] of eachWithIndex(anArray)) console.log(val, i)
Das Gute an Generatoren ist, dass sie faul sind und das Ergebnis eines anderen Generators als Argument akzeptieren können.
Das ist meine Version eines zusammengesetzten Iterators, der einen Index und den Wert einer übergebenen Generatorfunktion mit einem Beispiel für eine (langsame) Primärsuche liefert:
const eachWithIndex = (iterable) => {
return {
*[Symbol.iterator]() {
let i = 0
for(let val of iteratable) {
i++
yield [i, val]
}
}
}
}
const isPrime = (n) => {
for (i = 2; i < Math.floor(Math.sqrt(n) + 1); i++) {
if (n % i == 0) {
return false
}
}
return true
}
let primes = {
*[Symbol.iterator]() {
let candidate = 2
while (true) {
if (isPrime(candidate)) yield candidate
candidate++
}
}
}
for (const [i, prime] of eachWithIndex(primes)) {
console.log(i, prime)
if (i === 100) break
}