Döngü için ES6 dizi öğesi dizinine erişim


228

Bir for-of loop kullanarak dizi öğelerine erişebiliriz:

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

Geçerli dizine erişmek için bu kodu nasıl değiştirebilirim? Bunu forhe sözdizimi kullanarak başarmak istiyorum, ne forhe ne de for-in.

Yanıtlar:


351

Kullanım Array.prototype.keys:

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

Hem anahtara hem de değere erişmek istiyorsanız, yıkımArray.prototype.entries() ile kullanabilirsiniz :

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


64
Vaka birisi harikaları, ben test for-ofile .entries()ve onu kıyasla yavaş iki kat daha .forEach(). jsperf.com/for-of-vs-foreach-with-index

1
@ K48 bilmek güzel, es'de en hızlı olmak istiyorsanız "ters döngü" kullanın: incredible-web.com/blog/…
nimo23

3
Ne yazık ki, iç içe bir döngü içinde verim gerekir. İşlev, yieldanahtar kelime için kapsam sorunları oluşturduğundan forEach kullanılamaz . Ama benim kullanım durumu için dizine erişim gerekir, yani ... temel eski ;;döngü, sanırım.
Kyle Baker

2
@KyleBaker Peki bir for-loop ile sorun .entires()nedir?
Michał Perłakowski

1
Bunun yerine ters döngü jsperf.com/reverse-loop-vs-cache uzunluğunu önbelleğe alabilirsiniz . RAM'de büyük diziler oluşturmadan akışı işleyebildiğinizde tekrarlanabilir işleme için kullanışlıdır. Bu gibi durumlarda G / Ç gecikmesi olacağından döngü hızı darboğaz olmaz.
x'ES

289

Array#entries ikisine de ihtiyacınız varsa dizini ve değeri döndürür:

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

}

3
TypeScript ile: 'TS2495: Type IterableIterator bir dizi veya dize türü değil'. Bu çözülecek gibi görünüyor: github.com/Microsoft/TypeScript/pull/12346
Johannes

2
Ayrıca Internet Explorer desteklenmez.
Sammi

1
İyi değil. Örneğin DOM ile yinelenebilir diğer birçok yapıda, document.styleSheets[0].cssRules.entries()hatta document.styleSheets.entries()büyük olasılıkla bir hata atar. Yine kullanmak zorunda _.forEach()denlodash
Steven Pribilinskiy

2
@Steven: Dizine ihtiyacınız yoksa yapabilirsiniz for (var value of document.styleSheets) {}. Dizin ihtiyaç yoksa aracılığıyla ilk bir diziye değerini dönüştürebilirsiniz Array.from: for (let [index, value] of Array.from(document.styleSheets)) {}.
Felix Kling

1
Bu iyi! Array.fromFTW ise
Steven Pribilinskiy

28

Bu gösterişli yeni yerel işlevler dünyasında, bazen temelleri unutuyoruz.

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

Temiz, verimli ve yine breakde döngü yapabilirsiniz . Bonus! Ayrıca sondan başlayıp geriye doğru gidebilirsiniz i--!

Ek not: Döngü içinde çok fazla değer kullanıyorsanız, const value = arr[i];kolay ve okunabilir bir referans için döngünün üstünde yapmak isteyebilirsiniz .


1
Evet. İyi olan, açık ve basit. Oh, ve bunun gibi dizinin anahtarına / dizinine erişmek için süper kolay bir yolunuz var.
birleştirin

2
Bu arada, durum şöyle görünmelidir -> için (-1) olmadan (let i = 0; i <arr.length; i ++) veya dizinin tüm öğeleri arasında döngü oluşturmaz.
birleştirin

1
@Kombine İyi yakala! Cevabınızı notunuzu yansıtacak şekilde güncelledim.
chris

4
Hala breakbir for-ofve for (let [index, value] of array.entries())okumak çok daha kolay. Geri gitmek, eklemek kadar kolaydır .reverse().
Nigel

3
Bence bu soruya son derece kabul edilebilir bir cevap. Asla kabul edilen cevap olmayacak, ancak bu soruyu araştıran birkaç düzine kişiye veya daha fazlasına yardımcı oldu. SO bunun içindir.
Danoram

3

html / js bağlamında, modern tarayıcılarda, Dizilerden farklı yinelenebilir nesnelerle [Tekrarlanabilir] .entries () de kullanabiliriz:

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

    element.innerHTML = '#' + index

}

Evet, bu çalışır, oysa yukarıda @Steven Pribilinskiy tarafından belirtilen diğer DOM yöntemleri entries, kendileri için bir yöntemi olmayan nesneleri döndürür .
matanster

3

Bir for..ofdöngüde bunu elde edebiliriz array.entries(). array.entriesyeni bir Array iterator nesnesi döndürür. Bir yineleyici nesnesi, öğelerin o sıradaki mevcut konumunu izlerken, aynı anda yinelenebilir bir öğeden nasıl erişileceğini bilir.

Tüm next()yöntem yineleyici anahtar değer çiftleri olarak adlandırılır oluşturulur. Bu anahtar / değer çiftlerinde dizi dizini anahtar ve dizi öğesi değerdir.

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

Bir for..ofdöngü temelde bir yinelenebilir tüketen ve tüm elemanlar (kaputun altında bir yineleyici kullanarak) ilmekler. Bunu array.entries()şu şekilde birleştirebiliriz :

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

Sen gerekiyorsa Ayrıca indeksi kendinizi işleyebilir endeksi , Bunu gerek işin eğer anahtarı .

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

  i++;
}

0

Bir Arraydizi veya hatta dizi benzeri olmayan nesneler kullananlar için, kendi yinelenebilirinizi kolayca oluşturabilirsiniz, böylece yine de sadece aşağıdakilere sahip olan for ofşeyler için kullanabilirsiniz :localStoragelength

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;
}

Sonra sadece bir numara verin:

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
Soru bir for...ofdöngü sormuyorfor...in
Abraham Hernandez

3
for...inorijinal ECMAScript spesifikasyonunun bir parçasıdır (yani "es1"). Ayrıca, for...innesne özellikleri üzerinde yineleme yapmak için olduğunu unutmayın . Diziler üzerinde yinelenebilse de, beklenen sırada bunu yapamayabilir. MDN belgelerinde daha fazlasını görün
Boaz

0

Başka bir yaklaşım Array.prototype.forEach(),

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
}

for loop diziyi geçerken, indexof özelliği diziyle eşleşen dizinin değerini alır. PD bu yöntemin bazı kusurları vardır, bu yüzden meyve kullanın


2
Bu O (n ^ 2) zaman alır.
Harry

3
Performansın önemli olmadığı durumlarda, yinelenen meyve olduğunda bu hala tüm doğru indeksleri vermez. Örneğin, ["apple", "apple", "pear"]verilen dizinler 0, 0, 2yerine 0, 1, 2.
trichoplax
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.