Akses ke indeks elemen array ES6 di dalam for-of loop

227

Kita bisa mengakses elemen array menggunakan for-of loop:

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

Bagaimana saya bisa memodifikasi kode ini untuk mengakses indeks saat ini juga? Saya ingin mencapai ini menggunakan sintaks untuk, baik forEach maupun for-in.

Abdennour TOUMI
sumber

Jawaban:

349

Gunakan Array.prototype.keys:

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

Jika Anda ingin mengakses kunci dan nilainya, Anda dapat menggunakannya Array.prototype.entries()dengan merusak :

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

Michał Perłakowski
sumber
64
Dalam kasus seseorang keajaiban, saya diuji for-ofdengan .entries()dan itu dua kali lebih lambat dibandingkan dengan .forEach(). jsperf.com/for-of-vs-foreach-with-index
1
@ K48 senang tahu, gunakan "terbalik untuk-loop" jika Anda ingin memiliki tercepat di es: luar
biasa-web.com/blog/...
3
Sayangnya, saya perlu menghasilkan dari dalam loop bersarang. Tidak dapat menggunakan forEach, karena fungsi menciptakan masalah cakupan untuk yieldkata kunci. Tapi saya perlu akses ke indeks untuk kasus penggunaan saya, jadi ... ;;loop tua dasar itu, saya kira.
Kyle Baker
2
@KyleBaker Dan apa yang salah dengan for-of loop .entires()?
Michał Perłakowski
1
Alih-alih membalikkan loop Anda dapat men- cache panjang jsperf.com/reverse-loop-vs-cache . Bermanfaat untuk pemrosesan yang dapat diulang ketika Anda dapat memproses streaming tanpa membuat array besar dalam RAM. Kecepatan putaran tidak akan menjadi hambatan karena Anda akan memiliki latensi I / O dalam kasus tersebut.
x'ES
289

Array#entries mengembalikan indeks dan nilainya, jika Anda membutuhkan keduanya:

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

}
Felix Kling
sumber
3
Dengan TypeScript: 'TS2495: Type IterableIterator bukan tipe array atau tipe string'. Sepertinya ini akan diselesaikan: github.com/Microsoft/TypeScript/pull/12346
Johannes
2
Juga Internet Explorer tidak didukung.
Sammi
1
Tidak baik. Melempar kesalahan misalnya dengan document.styleSheets[0].cssRules.entries()atau bahkan document.styleSheets.entries()dan mungkin banyak struktur DOM lainnya yang dapat diubah. Masih harus menggunakan _.forEach()darilodash
Steven Pribilinskiy
2
@ Seven: Jika Anda tidak membutuhkan indeks, Anda bisa melakukannya for (var value of document.styleSheets) {}. Jika Anda perlu indeks Anda dapat mengkonversi nilai ke array pertama melalui Array.from: for (let [index, value] of Array.from(document.styleSheets)) {}.
Felix Kling
1
Itu bagus! Array.fromadalah FTW
Steven Pribilinskiy
28

Dalam dunia fungsi asli baru yang mencolok ini, kita terkadang melupakan dasar-dasarnya.

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

Bersih, efisien, dan Anda masih bisa breakmengulang. Bonus! Anda juga bisa mulai dari akhir dan mundur dengan i--!

Catatan tambahan: Jika Anda banyak menggunakan nilai dalam loop, Anda mungkin ingin melakukannya const value = arr[i];di bagian atas loop untuk referensi yang mudah dibaca.

chris
sumber
1
Ya. Bagus, jelas dan sederhana. Oh, dan seperti itu Anda memiliki cara super mudah untuk mengakses kunci / indeks array.
Gabungkan
2
By the way, kondisinya akan terlihat seperti ini -> untuk (misalkan i = 0; i <arr.length; i ++) tanpa (-1) atau tidak akan berulang di seluruh elemen array.
Gabungkan
1
@ Menggabungkan Tangkapan yang bagus! Saya telah memperbarui jawaban saya untuk mencerminkan catatan Anda.
chris
4
Anda masih breakseorang for-ofdan for (let [index, value] of array.entries())jauh lebih mudah dibaca. Mundur adalah semudah menambahkan .reverse().
Nigel B. Peck
2
Saya pikir ini adalah jawaban yang bisa diterima untuk pertanyaan ini. Itu tidak akan pernah menjadi jawaban yang diterima tetapi telah membantu beberapa lusin orang atau lebih yang telah mencari pertanyaan ini. Inilah gunanya SO.
Danoram
3

dalam konteks html / js, pada peramban modern, dengan objek lain yang dapat dihapus selain Array, kami juga dapat menggunakan [Iterable] .entries ():

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

    element.innerHTML = '#' + index

}
Joseph Merdrignac
sumber
Ya ini berfungsi, sedangkan yang lain yang disebutkan di atas oleh @Steven Pribilinskiy metode DOM lainnya mengembalikan objek yang tidak memiliki entriesmetode untuk mereka.
matanster
3

Dalam satu for..oflingkaran kita dapat mencapai ini melalui array.entries(). array.entriesmengembalikan objek iterator Array baru. Objek iterator tahu cara mengakses item dari item iterable pada saat itu, sambil melacak posisi saat ini dalam urutan itu.

Ketika next()metode ini dipanggil pada nilai kunci iterator, pasangan dihasilkan. Dalam pasangan nilai kunci ini indeks array adalah kunci dan item array adalah nilainya.

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

Sebuah for..ofloop pada dasarnya adalah sebuah konstruksi yang mengkonsumsi iterable dan loop melalui semua elemen (menggunakan iterator di bawah tenda). Kami dapat menggabungkan ini dengan array.entries()cara berikut:

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

Willem van der Veen
sumber
3

Anda juga dapat menangani indeks sendiri jika Anda memerlukan indeks , itu tidak akan berfungsi jika Anda membutuhkan kunci .

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

  i++;
}
TintinSansYeux
sumber
0

Bagi mereka yang menggunakan objek yang bukan Arrayatau bahkan seperti array, Anda dapat membangun iterable Anda sendiri dengan mudah sehingga Anda masih dapat menggunakan for ofuntuk hal-hal seperti localStorageyang benar-benar hanya memiliki 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;
}

Maka cukup beri nomor:

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

es6 for...in

for(const index in [15, 64, 78]) {                        
    console.log(index);
}
solanki ...
sumber
5
Pertanyaannya adalah bertanya tentang for...oflingkaran bukanfor...in
Abraham Hernandez
3
for...inadalah bagian dari spesifikasi ECMAScript asli (yaitu "es1"). Juga, perhatikan bahwa for...inini dimaksudkan untuk mengulangi properti objek. Meskipun dapat mengulangi lebih dari array, itu mungkin tidak melakukannya dalam urutan yang diharapkan. Lihat lebih banyak di dokumentasi MDN
Boaz
0

Pendekatan lain bisa menggunakan Array.prototype.forEach()sebagai

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

Saksham
sumber
-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 for melewati larik array, sementara properti indexof mengambil nilai indeks yang cocok dengan larik. Metode PD ini memiliki beberapa kekurangan dengan angka, jadi gunakan buah-buahan

Edwin Felipe
sumber
2
Ini membutuhkan waktu O (n ^ 2).
Harry
3
Dalam kasus di mana kinerja tidak penting, ini masih tidak memberikan semua indeks yang benar ketika ada duplikat buah. Misalnya, untuk ["apple", "apple", "pear"]indeks yang diberikan 0, 0, 2bukan 0, 1, 2.
trichoplax