Ketik Script untuk ... dengan indeks / kunci?

146

Seperti yang dijelaskan di sini, TypeScript memperkenalkan loop foreach:

var someArray = [9, 2, 5];
for (var item of someArray) {
    console.log(item); // 9,2,5
}

Tapi apakah tidak ada indeks / kunci? Saya mengharapkan sesuatu seperti:

for (var item, key of someArray) { ... }
Mick
sumber

Jawaban:

274

.forEach sudah memiliki kemampuan ini:

const someArray = [9, 2, 5];
someArray.forEach((value, index) => {
    console.log(index); // 0, 1, 2
    console.log(value); // 9, 2, 5
});

Tetapi jika Anda ingin kemampuan for...of, maka Anda dapat maparray ke indeks dan nilai:

for (const { index, value } of someArray.map((value, index) => ({ index, value }))) {
    console.log(index); // 0, 1, 2
    console.log(value); // 9, 2, 5
}

Itu agak lama, jadi mungkin membantu untuk menempatkannya dalam fungsi yang dapat digunakan kembali:

function toEntries<T>(a: T[]) {
    return a.map((value, index) => [index, value] as const);
}

for (const [index, value] of toEntries(someArray)) {
    // ..etc..
}

Versi Iterable

Ini akan berfungsi ketika menargetkan ES3 atau ES5 jika Anda mengkompilasi dengan --downlevelIterationopsi kompiler.

function* toEntries<T>(values: T[] | IterableIterator<T>) {
    let index = 0;
    for (const value of values) {
        yield [index, value] as const;
        index++;
    }
}

Array.prototype.entries () - ES6 +

Jika Anda dapat menargetkan lingkungan ES6 + maka Anda dapat menggunakan .entries()metode yang diuraikan dalam jawaban Arnavion .

David Sherret
sumber
Tetapi TypeScript mengkompilasi "untuk ... dari" menjadi "sederhana" untuk yang memiliki indeks var _i. Jadi mudah bagi pengembang TypeScript untuk mengizinkan kami menggunakan _i ini. Lihat contoh taman bermain: bit.ly/1R9SfBR
Mick
2
@Cocok tergantung target. Ketika mentransformasikan ke ES6 tidak melakukan itu. Alasan untuk kode tambahan saat transpiling hanya untuk mendapatkan kode ES6 berfungsi di versi sebelumnya.
David Sherret
3
Bagaimana Anda bisa istirahat; di forEach itu?
João Silva
Juga jawaban yang baik stackoverflow.com/questions/34348937/…
Christopher Grigg
@ JoãoSilva Anda dapat menggunakan Array.some()dan mengembalikan false pada iterasi yang ingin Anda hentikan. Ini tidak sejelas atau seindah breaktapi itu akan menyelesaikan pekerjaan. Secara pribadi saya tidak suka itu, saya mungkin akan menulis ulang iterasi dengan cara lain :) lihat stackoverflow.com/questions/2641347/…
Neek
35

"Old school javascript" untuk penyelamatan (bagi mereka yang tidak terbiasa / cinta pemrograman fungsional)

for (let i = 0; i < someArray.length ; i++) {
  let item = someArray[i];
}
Sylvain
sumber
2
Saya sebenarnya lebih suka jawaban ini. Tidak menggunakan metode tambahan hanya untuk menghasilkan indeks untuk setiap elemen.
bluegrounds
Terima kasih banyak muuuchh! Kami tidak tahu ini :)
TSR
14

Anda dapat menggunakan for..in Operator naskah untuk mengakses indeks ketika berhadapan dengan koleksi.

var test = [7,8,9];
for (var i in test) {
   console.log(i + ': ' + test[i]);
} 

Keluaran:

 0: 7
 1: 8
 2: 9

Lihat Demo

Karanvir Kang
sumber
Ketahuilah bahwa "i" adalah string yang bukan int dengan for..in loop. Melakukan operasi aritmatika dengan "i" akan menghasilkan rangkaian string. (i +1) akan sama dengan "01" misalnya ketika i = 0
Stéphane
for..injuga dapat memberi Anda lebih dari yang Anda harapkan karena mencakup semua fungsi yang dideklarasikan pada objek juga. Sebagai contoh:for (var prop in window.document) { console.log(prop); }
Ken Lyon
5

Atau solusi jadul lainnya:

var someArray = [9, 2, 5];
let i = 0;
for (var item of someArray) {
    console.log(item); // 9,2,5
    i++;
}
Galdor
sumber