Uwaga:
pytanie nadal dotyczy
for…of
pętli.> Nie używajfor…in
do iteracji po tablicy , użyj go do iteracji po właściwościach obiektu. To powiedziawszy to
Rozumiem, że podstawowa for…in
składnia w JavaScript wygląda następująco:
for (var obj in myArray) {
// ...
}
Ale jak uzyskać licznik / indeks pętli ?
Wiem, że prawdopodobnie mógłbym zrobić coś takiego:
var i = 0;
for (var obj in myArray) {
alert(i)
i++
}
Lub nawet stary dobry:
for (var i = 0; i < myArray.length; i++) {
var obj = myArray[i]
alert(i)
}
Wolałbym jednak użyć prostszej for-in
pętli. Myślę, że wyglądają lepiej i mają więcej sensu.
Czy istnieje prostszy lub bardziej elegancki sposób?
W Pythonie jest to łatwe:
for i, obj in enumerate(myArray):
print i
javascript
for-loop
foreach
counter
hobbes3
źródło
źródło
alert(obj)
?Odpowiedzi:
for…in
iteruje nazwy właściwości, a nie wartości, i robi to w nieokreślonej kolejności (tak, nawet po ES6). Nie należy go używać do iteracji po tablicach. Dla nich istniejeforEach
metoda ES5, która przekazuje zarówno wartość, jak i indeks do funkcji, którą dajesz:Lub ES6
Array.prototype.entries
, który ma teraz obsługę we wszystkich wersjach przeglądarki:Jednak w przypadku iteracji (gdzie
for…of
zamiast pętli użyłbyś pętlifor…in
), nie ma nic wbudowanego:próbny
Jeśli naprawdę miałeś na myśli
for…in
- wyliczanie właściwości - potrzebujesz dodatkowego licznika.Object.keys(obj).forEach
może działać, ale obejmuje tylko własne właściwości;for…in
zawiera wyliczalne właściwości w dowolnym miejscu łańcucha prototypu.źródło
let
s sąvar
o zasięgu blokowym.const
s są niezmienne.%d
formatuje liczbę całkowitą i%s
formatuje ciąg. Są oparte na printf . Specyfikacja jest w trakcie tworzenia na console.spec.whatwg.org/#formatter .W ES6 dobrze jest używać pętli -. Możesz uzyskać indeks dla tego typu
Zauważ, że
Array.entries()
zwraca iterator , który pozwala mu pracować w pętli for-of; nie myl tego z Object.entries () , która zwraca tablicę par klucz-wartość.źródło
entries()
wraca pusty obiekt:{}
. Masz pomysł, dlaczego tak jest? Myarray
is Array of Objects.Object.entries(array)
zamiastarray.entries()
next()
metodą, która zwróci kolejne wpisy w tablicy za każdym razem, gdy zostanie wywołane. Nie ma w nim (widocznych) danych; dostajesz dane w obiekcie bazowym, wywołującnext()
, co robi za kulisami. cc @tonygCo powiesz na to
Gdzie
array.forEach
ta metoda maindex
parametr będący indeksem bieżącego elementu przetwarzanego w tablicy.źródło
break
nie jest dostępny.Rozwiązanie dla małych kolekcji tablic:
arr - ARRAY, obj - KLUCZ bieżącego elementu, i - LICZNIK / INDEKS
Uwaga: Metoda keys () nie jest dostępna dla wersji IE <9, powinieneś użyć kodu Polyfill . https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
źródło
var i = 0;
ii++;
jest krótsza i bardziej wydajne. Ponadto nie działa w przypadku wyliczalnych właściwości, które nie są własnymi właściwościami.Pętle dla pętli iterują właściwości obiektu. Nie używaj ich do tablic, nawet jeśli czasami działają.
Właściwości obiektu nie mają wówczas indeksu, wszystkie są równe i nie trzeba ich przeglądać w określonej kolejności. Jeśli chcesz policzyć właściwości, będziesz musiał ustawić dodatkowy licznik (tak jak w pierwszym przykładzie).
zapętlić tablicę:
zapętlić obiekt:
źródło
(var i=0; i<a.length; i++)
tak , jak zmarnowane zasoby. Użyj(var i=0, var len = a.length; i<len; i++)
var i=0; i<a.length; i++)
jest to standardowy wzorzec pętli, który jest optymalizowany przez każdy przyzwoity silnik javascript.var i=0; i<a.length; i++
jest najlepszą praktyką.Jak powiedzieli inni, nie powinieneś używać for..in do iteracji po tablicy.
Jeśli chcesz czystszej składni, możesz użyć forEach:
Jeśli chcesz skorzystać z tej metody, upewnij się, że dołączasz podkładkę ES5, aby dodać obsługę starszych przeglądarek.
źródło
Odpowiedź udzielona przez rushUp jest poprawna, ale będzie to wygodniejsze
źródło
Oto funkcja,
eachWithIndex
która działa ze wszystkim, co można powtórzyć.Możesz także napisać podobną funkcję
eachWithKey
która działa z użyciem objetsfor...in
.Zaletą generatorów jest to, że są leniwi i mogą brać argument innego generatora jako argument.
źródło
To jest moja wersja iteratora złożonego, która daje indeks i wartość przekazanej funkcji generatora z przykładem (wolnego) wyszukiwania pierwszego:
źródło
eachWithIndex[Symbol.iterator]
zamiast samej funkcjieachWithIndex
?eachWithIndex
nie spełnia iterowalnego interfejsu, o co w tym wszystkim chodziSymbol.iterator
.eachWithIndex
aby zaakceptować iterowalny i zwrócić zamknięty iterowalny kompozyt.Oprócz bardzo dobrych odpowiedzi, które wszyscy napisali, chcę dodać, że najbardziej wydajnym rozwiązaniem jest ES6
entries
. Wydaje się, że dla wielu deweloperów jest to kontrowersyjne , więc stworzyłem ten doskonały benchmark .Jest ~ 6 razy szybszy. Głównie dlatego, że nie musi: a) uzyskiwać dostępu do tablicy więcej niż raz i b) rzutować indeks.
źródło