Loop melalui array di JavaScript

3147

Di Jawa Anda bisa menggunakan forloop untuk melintasi objek dalam array sebagai berikut:

String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
    // Do something
}

Bisakah Anda melakukan hal yang sama dalam JavaScript?

Mark Szymanski
sumber
5
Ok, jadi saya agak bingung, tidak apa-apa menggunakan loop yang disempurnakan ketika Anda mengakses objek? Dan gunakan yang berurutan untuk mengisinya? Apakah ini benar?
Mark Szymanski
45
tidak, ini benar-benar sederhana, objek array memiliki indeks numerik, jadi Anda ingin mengulangi indeks tersebut dalam urutan numerik, loop berurutan memastikan bahwa, loop yang ditingkatkan menyebutkan properti objek, tanpa urutan tertentu, dan juga menghitung properti yang diwarisi. .. untuk iterating melalui array loop berurutan selalu disarankan ...for-in
CMS
2
terkait - stackoverflow.com/questions/5349425/...
jondavidjohn
6
jsben.ch/#/Q9oD5 <= Di sini benchmark dari sekumpulan solusi untuk perulangan melalui array
EscapeNetscape
3
@ CMS Tidak, ini tidak terlalu sederhana. Ini sangat sederhana dalam setiap bahasa lainnya. Ini sangat rumit di JS, di mana Anda miliki indan ofitu dapat digunakan dan melakukan hal-hal yang berbeda. Kemudian Anda juga memiliki forEachdan pengulangan berbasis indeks jelek dan menjengkelkan. Setiap bahasa modern lainnya membuat pengulangan koleksi menjadi mudah dan langsung tanpa kejutan atau kebingungan. JS juga bisa, tetapi tidak.
jpmc26

Jawaban:

3965

Anda memiliki beberapa opsi:

1. forLoop berurutan :

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    console.log(myStringArray[i]);
    //Do something
}

Pro

  • Bekerja pada setiap lingkungan
  • Anda dapat menggunakan breakdan continuemengalirkan pernyataan kontrol

Cons

  • Terlalu bertele-tele
  • Imperatif
  • Mudah memiliki kesalahan satu per satu (kadang-kadang juga disebut kesalahan posting pagar )

2. Array.prototype.forEach

Spesifikasi ES5 memperkenalkan banyak metode array yang bermanfaat, salah satunya, Array.prototype.forEachdan memberikan kita cara ringkas untuk beralih ke array:

const array = ["one", "two", "three"]
array.forEach(function (item, index) {
  console.log(item, index);
});

Menjadi hampir sepuluh tahun saat penulisan spesifikasi ES5 dirilis (Desember 2009), telah diterapkan oleh hampir semua mesin modern di lingkungan desktop, server, dan seluler, sehingga aman untuk menggunakannya.

Dan dengan sintaks fungsi panah ES6, ini bahkan lebih ringkas:

array.forEach(item => console.log(item));

Fungsi panah juga diterapkan secara luas kecuali jika Anda berencana untuk mendukung platform kuno (misalnya, IE11); kamu juga aman untuk pergi.

Pro

  • Sangat singkat dan ringkas.
  • Deklaratif

Cons

  • Tidak bisa menggunakan break/continue

Biasanya, Anda dapat mengganti kebutuhan untuk breakkeluar dari loop imperatif dengan memfilter elemen array sebelum mengulanginya, misalnya:

array.filter(item => item.condition < 10)
     .forEach(item => console.log(item))

Perlu diingat jika Anda melakukan iterasi array untuk membangun array lain darinya , Anda harus menggunakan map, saya telah melihat anti-pola ini berkali-kali.

Anti-pola:

const numbers = [1,2,3,4,5], doubled = [];

numbers.forEach((n, i) => { doubled[i] = n * 2 });

Kasus penggunaan yang tepat dari peta :

const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);

console.log(doubled);

Selain itu, jika Anda mencoba mengurangi larik menjadi nilai, misalnya, Anda ingin menjumlahkan larik angka, Anda harus menggunakan metode pengurangan .

Anti-pola:

const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });

Penggunaan yang tepat dari pengurangan :

const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum);

3. for-ofPernyataan ES6

Standar ES6 memperkenalkan konsep objek iterable dan mendefinisikan konstruk baru untuk data traversing, for...ofpernyataan tersebut.

Pernyataan ini berfungsi untuk semua jenis objek yang dapat diulang dan juga untuk generator (objek apa pun yang memiliki [Symbol.iterator]properti).

Objek array adalah definisi bawaan bawaan di ES6, jadi Anda bisa menggunakan pernyataan ini pada mereka:

let colors = ['red', 'green', 'blue'];
for (const color of colors){
    console.log(color);
}

Pro

  • Itu dapat beralih pada berbagai macam objek.
  • Dapat menggunakan pernyataan kontrol aliran normal ( break/ continue).
  • Berguna untuk mengulangi nilai asinkron secara seri.

Cons

Jangan gunakan for...in

@zipcodeman menyarankan penggunaan for...inpernyataan, tetapi untuk iterating array for-inharus dihindari, pernyataan itu dimaksudkan untuk menyebutkan properti objek.

Seharusnya tidak digunakan untuk objek seperti array karena:

  • Urutan iterasi tidak dijamin; indeks array tidak dapat dikunjungi dalam urutan numerik.
  • Properti yang diwarisi juga disebutkan.

Poin kedua adalah bahwa hal itu dapat memberi Anda banyak masalah, misalnya, jika Anda memperluas Array.prototypeobjek untuk memasukkan metode di sana, properti itu juga akan disebutkan.

Sebagai contoh:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
    console.log(array[i]);
}

Kode di atas akan menghibur log "a", "b", "c", dan "foo!".

Itu menjadi masalah terutama jika Anda menggunakan beberapa perpustakaan yang sangat bergantung pada augmentasi prototipe asli (seperti MooTools, misalnya).

The for-inpernyataan seperti yang saya katakan sebelumnya ada untuk menghitung properti obyek, misalnya:

var obj = {
    "a": 1,
    "b": 2,
    "c": 3
};

for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) { 
        // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
        console.log("prop: " + prop + " value: " + obj[prop])
    }
}

Dalam contoh di atas, hasOwnPropertymetode ini memungkinkan Anda untuk menghitung hanya properti sendiri , hanya itu, hanya properti yang dimiliki objek secara fisik, tanpa properti yang diwariskan.

Saya akan merekomendasikan Anda untuk membaca artikel berikut:

CMS
sumber
21
Inilah alasannya (oleh CMS sendiri) stackoverflow.com/questions/1885317/…
OscarRyz
15
@DoubleGras, saya pikir itu adalah pendapat yang tidak dibagikan oleh semua orang. Lihat: stackoverflow.com/questions/5752906/… atau groups.google.com/forum/?fromgroups#!topic/jsmentors/…
Matthijs Wessels
3
Siapa pun yang berpikir Anda perlu panjang cache ... Silakan lihat jawaban saya, Anda bahkan tidak perlu mengaksesnya sekali pun, apalagi cache itu: untuk (var i = 0, item; item = myStringArray [i]; i ++) {/ * gunakan item di sini * /}
Stijn de Witt
15
@StijndeWitt Tidak, karena itu istirahat jika Anda memiliki "falsey" nilai-nilai dalam array: false, undefined, 0, "", NaN.
Phrogz
6
jsperf.com/caching-array-length/4 Berikut ini adalah tes untuk melihat apakah layak untuk caching panjang array dalam loop Javascript
Enrico
1116

Ya, dengan asumsi implementasi Anda mencakup for...of fitur yang diperkenalkan dalam ECMAScript 2015 (rilis "Harmony") ... yang merupakan asumsi yang cukup aman akhir-akhir ini.

Ini berfungsi seperti ini:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

Atau lebih baik lagi, karena ECMAScript 2015 juga menyediakan variabel blok-tertutup:

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

(Variabel sberbeda pada setiap iterasi, tetapi masih dapat dideklarasikan constdi dalam loop body selama itu tidak dimodifikasi di sana.)

Catatan tentang array jarang: array dalam JavaScript mungkin tidak benar-benar menyimpan item sebanyak yang dilaporkan oleh-nya length; angka yang dilaporkan hanyalah satu lebih besar dari indeks tertinggi tempat nilai disimpan. Jika array memiliki lebih sedikit elemen daripada yang ditunjukkan oleh panjangnya, itu dikatakan jarang . Misalnya, sangat sah untuk memiliki array dengan item hanya di indeks 3, 12, dan 247; yang dari array tersebut dilaporkan sebagai 248, meskipun itu hanya benar-benar menyimpan 3 nilai. Jika Anda mencoba mengakses item di indeks lain mana pun, array akan nampak memiliki nilai di sana. Jadi ketika Anda ingin "loop through" sebuah array, Anda memiliki pertanyaan untuk dijawab: apakah Anda ingin mengulang seluruh rentang yang ditunjukkan oleh panjang dan prosesnya untuk elemen yang hilang, atau apakah Anda hanya ingin memproses elemen yang benar-benar ada? Ada banyak aplikasi untuk kedua pendekatan; itu hanya tergantung pada apa yang Anda gunakan untuk array.lengthundefinedundefined

Jika Anda beralih di atas array dengan for.. of, badan loop dijalankan lengthkali, dan variabel kontrol loop diatur ke undefineduntuk setiap item yang tidak benar-benar hadir dalam array. Bergantung pada detail kode "lakukan sesuatu dengan" Anda, perilaku itu mungkin yang Anda inginkan, tetapi jika tidak, Anda harus menggunakan pendekatan yang berbeda.

Tentu saja, beberapa pengembang tidak punya pilihan selain menggunakan pendekatan yang berbeda pula, karena untuk alasan apa pun yang mereka menargetkan versi JavaScript yang belum mendukung for... of.

Selama implementasi JavaScript Anda sesuai dengan edisi sebelumnya dari spesifikasi ECMAScript (yang mengesampingkan, misalnya, versi Internet Explorer sebelum 9), maka Anda dapat menggunakan Array#forEachmetode iterator alih-alih loop. Dalam hal ini, Anda melewatkan fungsi untuk dipanggil pada setiap item dalam array:

var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

Tidak seperti for... of, .forEachhanya memanggil fungsi untuk elemen yang sebenarnya ada dalam array. Jika melewati susunan hipotesis kami dengan tiga elemen dan panjang 248, ia hanya akan memanggil fungsi tiga kali, bukan 248 kali. Ini juga membedakan antara elemen yang hilang dan elemen yang sebenarnya diatur undefined; untuk yang terakhir, masih akan memanggil fungsi, lewat undefinedsebagai argumen. Jika ini adalah bagaimana Anda ingin menangani array jarang, .forEachmungkin cara untuk pergi bahkan jika dukungan juru Anda for... of.

Opsi terakhir, yang bekerja di semua versi JavaScript, adalah loop penghitungan eksplisit . Anda cukup menghitung dari 0 hingga kurang dari panjang dan menggunakan penghitung sebagai indeks. Loop dasar terlihat seperti ini:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  s = myStringArray[i];
  // ... do something with s ...
}

Salah satu keuntungan dari pendekatan ini adalah Anda dapat memilih cara menangani array yang jarang; kode di atas akan menjalankan tubuh loop penuh lengthkali, dengan sset untuk undefineduntuk setiap elemen yang hilang, seperti for.. of. Jika Anda hanya ingin menangani elemen yang sebenarnya ada dari array jarang .forEach, Anda dapat menambahkan intes sederhana pada indeks:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do something with s ...
  }
}

Menetapkan nilai panjang ke variabel lokal (sebagai lawan untuk memasukkan myStringArray.lengthekspresi penuh dalam kondisi loop) dapat membuat perbedaan yang signifikan dalam kinerja karena melewatkan pencarian properti setiap kali; menggunakan Badak di mesin saya, speedup adalah 43%.

Anda mungkin melihat caching panjang dilakukan dalam klausul inisialisasi loop, seperti ini:

var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

Lingkaran penghitungan eksplisit juga berarti Anda memiliki akses ke indeks setiap nilai, jika Anda menginginkannya. Indeks ini juga diteruskan sebagai parameter tambahan ke fungsi yang Anda berikan forEach, sehingga Anda dapat mengaksesnya juga:

myStringArray.forEach( function(s, i) {
   // ... do something with s and i ...
});

for... oftidak memberi Anda indeks yang terkait dengan setiap objek, tetapi selama objek yang Anda iterasi sebenarnya adalah Array( for.. ofberfungsi untuk jenis iterable lainnya yang mungkin tidak memiliki metode ini), Anda dapat menggunakan Array Metode #entries untuk mengubahnya menjadi array pasangan [indeks, item], dan kemudian beralih lagi:

for (const [i, s] of myStringArray.entries()) {
  // ... do something with s and i ...
}

The for... insintaks disebutkan oleh orang lain adalah untuk mengulang melalui properti obyek; karena Array dalam JavaScript hanyalah sebuah objek dengan nama properti numerik (dan lengthproperti yang diperbarui secara otomatis ), Anda secara teoritis dapat mengulang Array dengannya. Tetapi masalahnya adalah bahwa itu tidak membatasi diri pada nilai properti numerik (ingat bahwa bahkan metode sebenarnya hanya properti yang nilainya merupakan penutupan), juga tidak dijamin untuk beralih daripada yang dalam urutan numerik. Oleh karena itu, for... insintaks tidak boleh digunakan untuk perulangan melalui Array.

Mark Reed
sumber
21
Perhatikan bahwa beberapa penerjemah (mis. V8) akan secara otomatis menyimpan panjang larik array jika kode dipanggil cukup kali dan mendeteksi bahwa panjangnya tidak diubah oleh loop. Meskipun panjang caching masih bagus, itu mungkin tidak memberikan peningkatan kecepatan ketika kode Anda dipanggil cukup kali untuk benar-benar membuat perbedaan.
Phrogz
2
@ mark-reed Bisakah Anda jelaskan mengapa Anda menggunakan i in myStringArraycontoh Anda? Bagaimana itu bisa salah?
Denis V
2
@DenisV: false a=[1,2,3,4]; delete a[2]; for (j in a) { console.log(j); } keluaran 0, 1, 3, dan 4. a.lengthmasih 5.
Mark Reed
1
Saya tidak menyarankan for j in a. Saya menunjukkan bahwa incek tersebut tidak berlebihan, seperti yang Anda nyatakan, dengan menunjukkan semua indeks dan menunjukkan bahwa ada satu di antara 0 dan length-1yang tidak ada. Saya juga bisa saja mencetak 2 in a, yang memang false, terlepas dari kenyataan bahwa Anda mengatakan itu tidak mungkin.
Mark Reed
2
@GrijeshChauhan - benar. Misalnya, IE hingga versi 8 tidak mendukungnya. Lihat pertanyaan ini .
Mark Reed
442

Anda dapat menggunakan map, yang merupakan teknik pemrograman fungsional yang juga tersedia dalam bahasa lain seperti Python dan Haskell .

[1,2,3,4].map( function(item) {
     alert(item);
})

Sintaks umumnya adalah:

array.map(func)

Secara umum funcakan mengambil satu parameter, yang merupakan item dari array. Tetapi dalam kasus JavaScript, dapat mengambil parameter kedua yang merupakan indeks item, dan parameter ketiga yang merupakan array itu sendiri.

Nilai kembalian dari array.maparray lain, sehingga Anda dapat menggunakannya seperti ini:

var x = [1,2,3,4].map( function(item) {return item * 10;});

Dan sekarang x adalah [10,20,30,40].

Anda tidak harus menulis fungsi sebaris. Bisa jadi fungsi yang terpisah.

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

yang akan setara dengan:

 for (item in my_list) {item_processor(item);}

Kecuali Anda tidak mendapatkan new_list.

Hasen
sumber
7
Tidak, tapi itu bisa lebih kuat. lihat ini: joelonsoftware.com/items/2006/08/01.html
hasen
97
Contoh khusus itu mungkin lebih baik diimplementasikan menggunakan Array.forEach. mapadalah untuk menghasilkan array baru.
harto
21
@hasen, Array.prototype.mapmetode ini merupakan bagian dari Standar ECMAScript Edisi 5, belum tersedia pada semua implementasi (mis. IE tidak memilikinya), juga untuk iterating melalui array. Saya pikir Array.prototype.forEachmetode ini lebih benar secara semantik ... juga tolong jangan ' t menyarankan pernyataan untuk-masuk, lihat jawaban saya untuk lebih jelasnya :)
CMS
3
Perbedaan antara forEachdan mapadalah bahwa yang pertama tidak mengembalikan hasil iterasi. map(Kadang-kadang alias collect, tetapi sangat berbeda dari apply) secara tegas untuk mengubah setiap elemen dari array menjadi hasil yang sesuai; ini pemetaan 1-ke-1 , karenanya namanya. Ini adalah bagian dari seluruh keluarga operasi yang mencakup reduce(yang menghasilkan hasil tunggal dari seluruh array) dan filter(yang menghasilkan subset dari array asli) dan seterusnya. Padahal forEachhanya melakukan sesuatu dengan setiap elemen, semantik tidak ditentukan.
Mark Reed
4
Downvote karena jika Anda tidak benar-benar memetakan sesuatu, maka menggunakan [] .map menyesatkan. [] .forEach masuk akal semantik dan juga melewati tiga argumen yang sama ke fungsi.
gengkev
120

Dalam JavaScript, tidak disarankan untuk mengulang melalui Array dengan for-in loop, tetapi lebih baik menggunakan forloop seperti:

for(var i=0, len=myArray.length; i < len; i++){}

Ini dioptimalkan juga ("caching" panjang array). Jika Anda ingin mempelajari lebih lanjut, baca posting saya tentang masalah ini .

sebarmeli
sumber
2
myArray.forEach (fungsi (obj) {}); masih yang terbaik
Jan Sverre
perbaikan kecil: Anda bisa menggunakan ++ibukannyai++
roberkules
14
++iadalah optimasi sekolah lama yang dilakukan oleh kompiler modern untuk Anda dalam for for sejak dulu :) stackoverflow.com/a/1547433/1033348
ngryman
6
Anda harus berhati-hati menggunakan loop ini. Saya mulai menggunakannya dan mengalami kesulitan melacak bug karena satu kesalahan yang saya buat. Jika Anda membuat dua loop seperti ini: jsfiddle.net/KQwmL/1 . Anda harus berhati-hati memberi nama var len secara berbeda di kedua loop, jika tidak loop kedua akan menimpa len pertama.
Rui Marques
1
Rui Marques - Anda dapat memberi nama variabel i_stopatau i_endbukan len. Ini hanya dapat dibaca (jika tidak lebih dari itu!), Dan Anda secara alami akan menghindari masalah semacam ini (karena loop Anda yang lain akan mendapatkan, misalnya, j_stop).
Chip Hogg
119

untuk (mis. myStringArray) {

(Langsung menjawab pertanyaan Anda: sekarang Anda bisa!)

Sebagian besar jawaban lain benar, tetapi mereka tidak menyebutkan (pada tulisan ini) bahwa ECMA Script  6  2015 membawa mekanisme baru untuk melakukan iterasi, for..ofloop.

Sintaks baru ini adalah cara paling elegan untuk melakukan iterasi array di javascript (selama Anda tidak memerlukan indeks iterasi).

Saat ini bekerja dengan Firefox 13+, Chrome 37+ dan tidak berfungsi dengan browser lain (lihat kompatibilitas browser di bawah). Untungnya kami memiliki kompiler JS (seperti Babel ) yang memungkinkan kami untuk menggunakan fitur generasi mendatang hari ini.

Ini juga berfungsi pada Node (saya mengujinya pada versi 0.12.0).

Iterasi sebuah array

// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) { 
   console.log(letter); 
}

Iterasi berbagai objek

var band = [
  {firstName : 'John', lastName: 'Lennon'}, 
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(var member of band){
  console.log(member.firstName + ' ' + member.lastName); 
}

Iterasi generator:

(Contoh diekstrak dari https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of )

function* fibonacci() { // a generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

Tabel kompatibilitas: http://kangax.github.io/es5-compat-table/es6/#For..of loop

Spec: http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}

Marlon Bernardes
sumber
Jika Anda menggunakan ES6, saya sarankan const sbukanvar s
joeytwiddle
Dalam pengujian saya pada array besar, menggunakan var s of arrhampir dua kali lipat (1.9x) waktu eksekusi dibandingkan dengan menggunakan penghitung sederhana untuk-loop dan mengambil elemen dengan indeks dalam nodejs
theferrit32
Mengapa hal aneh itu ada di baris pertama dan terakhir?
Peter Mortensen
91

Opera, Safari, Firefox, dan Chrome sekarang semuanya berbagi serangkaian metode Array yang disempurnakan untuk mengoptimalkan banyak loop umum.

Anda mungkin tidak membutuhkan semuanya, tetapi mereka bisa sangat berguna, atau jika semua browser mendukungnya.

Mozilla Labs menerbitkan algoritme yang mereka dan WebKit gunakan, sehingga Anda dapat menambahkannya sendiri.

filter mengembalikan array item yang memenuhi beberapa kondisi atau pengujian.

setiap mengembalikan true jika setiap anggota array lulus tes.

beberapa mengembalikan true jika ada yang lulus tes.

forEach menjalankan fungsi pada setiap anggota array dan tidak mengembalikan apa pun.

map seperti forEach, tetapi mengembalikan array hasil operasi untuk setiap elemen.

Metode-metode ini semua mengambil fungsi untuk argumen pertama mereka dan memiliki argumen kedua opsional, yang merupakan objek yang cakupannya ingin Anda terapkan pada anggota array saat mereka mengulangi fungsi.

Abaikan sampai Anda membutuhkannya.

indexOf dan lastIndexOf menemukan posisi yang tepat dari elemen pertama atau terakhir yang cocok dengan argumennya.

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this))
                        return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what)
                    return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L)
                i= L-1;
            else
                if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what)
                    return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this))
                        return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p])
            ap[p]= p2[p];
    }
    return true;
})();
kennebec
sumber
1
Tambahan: IE mendukung forEach sejak versi 9, lihat forEach Method MSDN
rwitzel
75

Intro

Sejak saya masih kuliah, saya sudah memprogram di Java, JavaScript, Pascal, ABAP , PHP, Progress 4GL, C / C ++ dan mungkin beberapa bahasa lain yang tidak dapat saya pikirkan saat ini.

Sementara mereka semua memiliki keistimewaan linguistik mereka sendiri, masing-masing bahasa ini memiliki banyak konsep dasar yang sama. Konsep-konsep tersebut meliputi prosedur / fungsi, IFpernyataan, FOR-loop, dan WHILE-loop.


for-Lingkaran tradisional

forLoop tradisional memiliki tiga komponen:

  1. Inisialisasi: dijalankan sebelum blok tampilan dieksekusi pertama kali
  2. Kondisi: memeriksa suatu kondisi setiap kali sebelum blok loop dieksekusi, dan berhenti loop jika salah
  3. Afterthought: dilakukan setiap kali setelah blok loop dieksekusi

Ketiga komponen ini dipisahkan satu sama lain oleh ;simbol. Konten untuk masing-masing dari ketiga komponen ini adalah opsional, yang berarti bahwa yang berikut ini adalah forloop seminimal mungkin:

for (;;) {
    // Do stuff
}

Tentu saja, Anda perlu memasukkan if(condition === true) { break; } atau di suatu if(condition === true) { return; }tempat di dalam for-loop untuk menghentikannya.

Meskipun demikian, biasanya inisialisasi digunakan untuk mendeklarasikan indeks, kondisi ini digunakan untuk membandingkan indeks itu dengan nilai minimum atau maksimum, dan setelahnya digunakan untuk meningkatkan indeks:

for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}

Menggunakan forloop tradisional untuk loop melalui array

Cara tradisional untuk mengulang melalui array, adalah ini:

for (var i = 0, length = myArray.length; i < length; i++) {
    console.log(myArray[i]);
}

Atau, jika Anda lebih suka mengulang ke belakang, Anda melakukan ini:

for (var i = myArray.length - 1; i > -1; i--) {
    console.log(myArray[i]);
}

Namun, ada banyak variasi yang mungkin, seperti misalnya yang ini:

for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
    console.log(value);
}

... atau yang ini ...

var i = 0, length = myArray.length;
for (; i < length;) {
    console.log(myArray[i]);
    i++;
}

... atau yang ini:

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

Apapun yang paling berhasil adalah masalah selera pribadi dan kasus penggunaan khusus yang Anda laksanakan.

Perhatikan bahwa masing-masing variasi ini didukung oleh semua browser, termasuk yang sangat lama!


Satu whilelingkaran

Satu alternatif untuk satu forloop adalah satu whileloop. Untuk mengulang melalui array, Anda bisa melakukan ini:

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

Seperti forloop tradisional , whileloop didukung bahkan oleh browser tertua.

Juga, perhatikan bahwa setiap loop sementara dapat ditulis ulang sebagai forloop. Sebagai contoh, whileloop di sini berperilaku dengan cara yang sama persis seperti ini for-loop:

for(var key = 0; value = myArray[key++];){
    console.log(value);
}

For...in dan for...of

Dalam JavaScript, Anda juga dapat melakukan ini:

for (i in myArray) {
    console.log(myArray[i]);
}

Ini harus digunakan dengan hati-hati, karena tidak berperilaku sama dengan forloop tradisional dalam semua kasus, dan ada efek samping potensial yang perlu dipertimbangkan. Lihat Mengapa menggunakan "untuk ... dalam" dengan iterasi array adalah ide yang buruk? untuk lebih jelasnya.

Sebagai alternatif for...in, sekarang ada juga untuk for...of. Contoh berikut menunjukkan perbedaan antara for...ofloop dan for...inloop:

var myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

for (var i of myArray) {
  console.log(i); // logs 3, 5, 7
}

Selain itu, Anda perlu mempertimbangkan bahwa tidak ada versi Internet Explorer yang mendukung for...of( Edge 12+ tidak) dan yang for...inmembutuhkan setidaknya Internet Explorer 10.


Array.prototype.forEach()

Alternatif untuk for-loops adalah Array.prototype.forEach(), yang menggunakan sintaks berikut:

myArray.forEach(function(value, key, myArray) {
    console.log(value);
});

Array.prototype.forEach() didukung oleh semua browser modern, serta Internet Explorer 9 dan yang lebih baru.


Perpustakaan

Akhirnya, banyak perpustakaan utilitas juga memiliki foreachvariasi sendiri . AFAIK, tiga yang paling populer adalah ini:

jQuery.each(), di jQuery :

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each(), di Underscore.js :

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach(), di Lodash.js :

_.forEach(myArray, function(value, key) {
    console.log(value);
});
John Slegers
sumber
68

Gunakan loop sementara ...

var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
    console.log(item);
}

log: 'satu', 'dua', 'tiga'

Dan untuk urutan terbalik, loop yang lebih efisien

var items = ['one','two','three'], i = items.length;
while(i--){
    console.log(items[i]);
}

log: 'tiga', 'dua', 'satu'

Atau forlingkaran klasik

var items = ['one','two','three']
for(var i=0, l = items.length; i < l; i++){
    console.log(items[i]);
}

log: 'satu', 'dua', 'tiga'

Referensi: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/

Timo Huovinen
sumber
21
Contoh pertama sintaks "while" tidak akan bekerja jika ada elemen array yang salah.
Chris Cooper
2
... dan loop sementara ini setara dengan: untuk (var i = 0, item; item = item [i]; i ++), yang menghilangkan kebutuhan untuk mendeklarasikan variabel indeks dan item sebelumnya ...
Stijn de Witt
39

Jika Anda ingin cara singkat untuk menulis perulangan cepat dan Anda dapat mengulanginya secara terbalik:

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

Ini memiliki keuntungan dari caching panjang (mirip dengan for (var i=0, len=myArray.length; i<len; ++i)dan tidak seperti for (var i=0; i<myArray.length; ++i)) sementara menjadi lebih sedikit karakter untuk diketik.

Bahkan ada saat-saat ketika Anda harus mengulang secara terbalik, seperti ketika mengulangi NodeList langsung di mana Anda berencana untuk menghapus item dari DOM selama iterasi.

Phrogz
sumber
16
Untuk orang-orang yang tidak mendapatkan apa yang begitu cerdik: Ekspresi i-- pertama kali dievaluasi dan memungkinkan perulangan untuk melanjutkan ketika itu tidak palsu ... Setelah itu penghitung dikurangi. Begitu saya menjadi nol itu akan keluar dari loop sebagai nol adalah nilai palsu dalam Javascript.
Stijn de Witt
5
kepalsuan? Maksudmu falsey. Mari kita semua tetap menggunakan terminologi yang tepat untuk menghindari kebingungan;)
danwellman
4
Saya telah melihat istilah falsish digunakan oleh orang yang saya anggap guru. Jika itu cukup baik untuk mereka, itu cukup baik untuk saya. Juga tetapi kecewa melihat bahwa komentar saya yang sebenarnya ontopic dan menambahkan penjelasan / wawasan mendapat 0 upvotes, tetapi komentar bahwa nitpicks pada suatu istilah dalam komentar saya mendapat 4. Ah yah hanya masalah prioritas kurasa.
Stijn de Witt
"Caching the length"? Panjangnya disimpan sebagai integer dalam array, itu tidak diukur setiap kali Anda mengaksesnya. Tidak ada manfaatnya menyalin nilai panjang ke variabel lain.
Mouscellaneous
1
@Mouscellaneous Hari-hari ini tentu saja tidak ada; dalam beberapa tahun terakhir iterasi array JavaScript caching panjang di sisi JavaScript (alih-alih mencapai seluruh implementasi) adalah keuntungan perf yang jelas (ketika microoptimizing). Sebagai contoh, for (var i=0,len=array.length;i<len;++i)adalah pengulangan yang umum dan masuk akal untuk ditulis.
Phrogz
36

Beberapa kasus menggunakan perulangan melalui array dengan cara pemrograman fungsional dalam JavaScript:

1. Hanya loop melalui array

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

Catatan: Array.prototype.forEach () bukan merupakan cara yang fungsional, karena fungsi yang diperlukan karena parameter input tidak seharusnya mengembalikan nilai, yang dengan demikian tidak dapat dianggap sebagai fungsi murni.

2. Periksa apakah ada elemen dalam array yang lulus tes

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3. Transformasikan ke array baru

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

Catatan: Metode map () membuat array baru dengan hasil memanggil fungsi yang disediakan pada setiap elemen dalam array panggilan.

4. Jumlahkan properti tertentu, dan hitung rata-rata

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5. Buat array baru berdasarkan yang asli tetapi tanpa mengubahnya

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6. Hitung jumlah setiap kategori

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7. Ambil subset array berdasarkan kriteria tertentu

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

Catatan: Metode filter () membuat array baru dengan semua elemen yang lulus tes diimplementasikan oleh fungsi yang disediakan.

8. Urutkan sebuah array

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

masukkan deskripsi gambar di sini

9. Temukan elemen dalam array

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

masukkan deskripsi gambar di sini

Metode Array.prototype.find () mengembalikan nilai elemen pertama dalam array yang memenuhi fungsi pengujian yang disediakan.

Referensi

Yuci
sumber
30

Ada cara untuk melakukannya di mana Anda memiliki sangat sedikit ruang lingkup implisit dalam loop Anda dan menghapus variabel tambahan.

var i = 0,
     item;

// note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){ 
    item; // This is the string at the index.
}

Atau jika Anda benar-benar ingin mendapatkan id dan memiliki forloop yang benar-benar klasik :

var i = 0,
    len = myStringArray.length; // cache the length

for ( ; i < len ; i++ ){
    myStringArray[i]; // Don't use this if you plan on changing the length of the array
}

Browser modern semua metode dukungan iterator forEach, map, reduce, filterdan sejumlah metode lain pada prototipe Array .

Gabriel
sumber
3
Perhatikan bahwa beberapa penerjemah (mis. V8) akan secara otomatis menyimpan panjang larik array jika kode dipanggil cukup kali dan mendeteksi bahwa panjangnya tidak diubah oleh loop.
Phrogz
Terima kasih atas info @Phrogz memang benar bahwa ada banyak optimisasi yang dapat dilakukan oleh VM, tetapi karena browser lama tidak memiliki ini, masih akan menjadi praktik terbaik untuk mengoptimalkannya karena sangat murah.
Gabriel
1
@ Gabriel: Kenapa? Tolong beri contoh dunia nyata yang menunjukkan bahwa tidak panjang cache sebenarnya adalah hambatan kinerja. Saya mengikuti pendekatan 'optimasi prematur adalah akar dari semua kejahatan'. Saya akan memperbaiki satu loop yang benar-benar menimbulkan masalah setelah saya temui ...
Stijn de Witt
1
@StijndeWitt imo itu hanya masalah gaya. Jujur saya bahkan tidak lagi menggunakan untuk loop melainkan mengandalkan garis bawah untuk hal-hal seperti _.each, _.map dll untuk melakukan hal-hal ini. Ketika saya menulis loop seperti ini, saya membuat cache panjang terutama sehingga semua deklarasi variabel saya berada di satu tempat, di bagian atas fungsi saya. Mengikuti saran saya dalam hal ini tidak penting bagi aplikasi dunia nyata mana pun. Optimalisasi prematur sangat buruk, tetapi jika optimasi terjadi akibat dari keputusan gaya saya tidak berpikir itu benar-benar penting.
Gabriel
1
@Gabriel Saya yakin JavaScript sudah mendukung fungsi peta pada array, tidak perlu memperkenalkan lib tambahan untuk itu.
Noz
28

Ada berbagai cara untuk mengulang array di JavaScript.

Loop umum:

var i;
for (i = 0; i < substr.length; ++i) {
    // Do something with `substr[i]`
}

Masing-masing ES5:

substr.forEach(function(item) {
    // Do something with `item`
});

jQuery.each:

jQuery.each(substr, function(index, item) {
    // Do something with `item` (or `this` is also `item` if you like)
});

Lihat ini untuk informasi terperinci atau Anda juga dapat memeriksa MDN untuk mengulang melalui array di JavaScript & menggunakan jQuery untuk memeriksa jQuery .

RizN81
sumber
27

Saya benar-benar akan merekomendasikan memanfaatkan perpustakaan underscore.js . Ini memberi Anda berbagai fungsi yang dapat Anda gunakan untuk beralih di atas array / koleksi.

Contohnya:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
Andrew Thomson
sumber
7
Untuk penemu baru dari pertanyaan ini, saya hanya ingin menunjukkan Lo-Dash , seorang penerus spiritual dari Underscore yang meningkatkannya dalam banyak hal.
Mark Reed
3
Mengapa menggunakan underscorejika ECMA-262 telah ditambahkan forEachmethor. Kode asli selalu lebih baik.
Walter Chapilliquen - wZVanG
27

Lingkaran array:

for(var i = 0; i < things.length; i++){
    var thing = things[i];
    console.log(thing);
}

Lingkaran objek:

for(var prop in obj){
    var propValue = obj[prop];
    console.log(propValue);
}
bzim
sumber
27

Ya , Anda dapat melakukan hal yang sama dalam JavaScript menggunakan loop, tetapi tidak terbatas pada itu, ada banyak cara untuk melakukan loop over array dalam JavaScript. Bayangkan Anda memiliki larik ini di bawah, dan Anda ingin mengulanginya:

var arr = [1, 2, 3, 4, 5];

Ini solusinya:

1) Untuk loop

Sebuah forlingkaran adalah cara yang umum perulangan melalui array dalam JavaScript, tetapi tidak ada dianggap sebagai solusi tercepat untuk array besar:

for (var i=0, l=arr.length; i<l; i++) {
  console.log(arr[i]);
}

2) Sementara loop

Loop sementara dianggap sebagai cara tercepat untuk mengulang melalui array panjang, tetapi biasanya kurang digunakan dalam kode JavaScript:

let i=0;

while (arr.length>i) {
    console.log(arr[i]);
    i++;
}

3) Lakukan ketika
A do whilemelakukan hal yang sama whiledengan beberapa perbedaan sintaksis seperti di bawah ini:

let i=0;
do {
  console.log(arr[i]);
  i++;
}
while (arr.length>i);

Ini adalah cara utama untuk melakukan loop JavaScript, tetapi ada beberapa cara lain untuk melakukannya.

Kami juga menggunakan for inloop untuk mengulang objek di JavaScript.

Juga melihat map(), filter(), reduce(), dll fungsi pada Array dalam JavaScript. Mereka mungkin melakukan banyak hal lebih cepat dan lebih baik daripada menggunakan whiledan for.

Ini adalah artikel yang bagus jika Anda ingin mempelajari lebih lanjut tentang fungsi-fungsi asinkron di atas array dalam JavaScript.

Pemrograman fungsional telah membuat percikan di dunia pengembangan saat ini. Dan untuk alasan yang baik: Teknik fungsional dapat membantu Anda menulis lebih banyak kode deklaratif yang lebih mudah dipahami sekilas, refactor, dan pengujian.

Salah satu landasan pemrograman fungsional adalah penggunaan khusus daftar dan operasi daftar. Dan hal-hal itu persis seperti apa itu: susunan benda, dan hal-hal yang Anda lakukan pada mereka. Tetapi pola pikir fungsional memperlakukan mereka sedikit berbeda dari yang Anda harapkan.

Artikel ini akan mencermati apa yang saya suka sebut operasi daftar "tiga besar": memetakan, memfilter, dan mengurangi. Membungkus kepala Anda di sekitar ketiga fungsi ini adalah langkah penting menuju kemampuan untuk menulis kode fungsional yang bersih, dan membuka pintu ke teknik pemrograman fungsional dan reaktif yang sangat kuat.

Ini juga berarti Anda tidak perlu lagi menulis for for loop.

Baca lebih lanjut >> di sini :

Alireza
sumber
Apakah benar-benar ada perbedaan kinerja sebelum loop for dan loop sementara ketika iterasi melalui array? Saya mendapat kesan bahwa perbedaan utamanya adalah sintaksis
shea
24

Jika ada yang tertarik pada sisi kinerja beberapa mekanisme yang tersedia untuk iterasi Array, saya telah menyiapkan tes JSPerf berikut:

https://jsperf.com/fastest-array-iterator

Hasil kinerja

Hasil:

for()Iterator tradisional , sejauh ini merupakan metode tercepat, terutama ketika digunakan dengan panjang array yang di-cache .

let arr = [1,2,3,4,5];

for(let i=0, size=arr.length; i<size; i++){
    // Do something
}

Metode Array.prototype.forEach()dan Array.prototype.map()adalah pendekatan paling lambat, mungkin sebagai konsekuensi dari panggilan fungsi overhead .

colxi
sumber
lebih baik digunakan i = i +1daripadai++
DarckBlezzer
2
Dapat ditingkatkan: Silakan gunakan: ++ i bukannya i ++, ini akan menghindari objek sementara. Jadi itu mengurangi penggunaan memori dan waktu cpu (tidak ada alokasi yang diperlukan)!
PowerStat
@ PowerStat dapatkah Anda memberikan tautan atau referensi tentang itu? Saya tidak pernah mendengarnya, terdengar menarik ...
colxi
1
@colxi Untuk hal-hal menarik seperti itu, Anda harus membaca hardcore C ++ dari Herb Sutter dan Scott Meyers. Hal ++ i vs i ++ berasal dari buku: Luar Biasa C ++: 47 Teka-teki Teknik, Masalah Pemrograman, dan Solusi - Saya juga bisa menemukannya di gotw.ca tetapi dapat dibuktikan untuk setiap bahasa pemrograman.
PowerStat
21

Jika Anda menggunakan perpustakaan jQuery, pertimbangkan untuk menggunakan http://api.jquery.com/jQuery.each/

Dari dokumentasi:

jQuery.each( collection, callback(indexInArray, valueOfElement) )

Pengembalian: Objek

Deskripsi: Fungsi iterator generik, yang dapat digunakan untuk beralih mulus pada kedua objek dan array. Array dan objek mirip array dengan properti panjang (seperti objek argumen fungsi) diulang dengan indeks numerik, dari 0 hingga panjang-1. Objek lain diulangi melalui properti yang disebutkan namanya.

The $.each()fungsi tidak sama dengan $(selector).each()yang digunakan untuk iterate, eksklusif, lebih objek jQuery. The $.each() fungsi dapat digunakan untuk iterate atas koleksi apapun, apakah itu adalah peta (object JavaScript) atau array. Dalam kasus array, callback dilewatkan indeks array dan nilai array yang sesuai setiap kali. (Nilai juga dapat diakses melalui thiskata kunci, tetapi Javascript akan selalu membungkus thisnilai sebagai Objectbahkan jika itu adalah string sederhana atau nilai angka.) Metode mengembalikan argumen pertama, objek yang diulangi.

justingordon
sumber
9
jQuery untuk semuanya?
Pengecualian
6
Setuju dengan Pengecualian. Jangan meremehkan dampak ketergantungan tambahan. Saya akan menyarankan hal ini kecuali dalam kode yang sudah banyak menggunakan jQuery.
Stijn de Witt
2
Pembaruan: Saat ini, Anda dapat menggunakan Array.forEach untuk mendapatkan banyak efek yang sama dengan array asli.
Stijn de Witt
21

Saya belum melihat variasi ini, yang secara pribadi saya sukai:

Diberikan array:

var someArray = ["some", "example", "array"];

Anda dapat mengulanginya tanpa pernah mengakses properti panjang:

for (var i=0, item; item=someArray[i]; i++) {
  // item is "some", then "example", then "array"
  // i is the index of item in the array
  alert("someArray[" + i + "]: " + item);
}

Lihat JsFiddle ini menunjukkan bahwa: http://jsfiddle.net/prvzk/

Ini hanya berfungsi untuk array yang tidak jarang. Artinya sebenarnya ada nilai di setiap indeks dalam array. Namun, saya menemukan bahwa dalam praktiknya saya jarang menggunakan array jarang dalam JavaScript ... Dalam kasus seperti itu, biasanya jauh lebih mudah untuk menggunakan objek sebagai peta / hashtable. Jika Anda memiliki array jarang, dan ingin mengulang lebih dari 0 .. panjang-1, Anda memerlukan untuk (var i = 0; i <someArray.length; ++ i) membangun, tetapi Anda masih memerlukan ifdi dalam loop untuk memeriksa apakah elemen pada indeks saat ini benar-benar ditentukan.

Juga, seperti yang disebutkan oleh CMS dalam komentar di bawah, Anda hanya dapat menggunakan ini pada array yang tidak mengandung nilai-nilai palsu. Array string dari contoh berfungsi, tetapi jika Anda memiliki string kosong, atau angka 0 atau NaN, dll. Loop akan terputus sebelum waktunya. Sekali lagi dalam prakteknya ini hampir tidak pernah menjadi masalah bagi saya, tetapi ini adalah sesuatu yang perlu diingat, yang membuat ini menjadi loop untuk dipikirkan sebelum Anda menggunakannya ... Itu mungkin mendiskualifikasi untuk beberapa orang :)

Yang saya sukai dari loop ini adalah:

  • Ini singkat untuk ditulis
  • Tidak perlu mengakses (apalagi cache) properti panjang
  • Item yang akan diakses secara otomatis ditentukan dalam loop body di bawah nama yang Anda pilih.
  • Menggabungkan secara alami dengan array.push dan array.splice untuk menggunakan array seperti daftar / tumpukan

Alasan ini berfungsi adalah bahwa spesifikasi array mengamanatkan bahwa ketika Anda membaca item dari indeks> = panjang array, itu akan kembali tidak terdefinisi. Ketika Anda menulis ke lokasi seperti itu sebenarnya akan memperbarui panjangnya.

Bagi saya, konstruk ini paling mirip dengan sintaksis Java 5 yang saya sukai:

for (String item : someArray) {
}

... dengan manfaat tambahan juga mengetahui tentang indeks saat ini di dalam loop

Stijn de Witt
sumber
14
Perhatikan bahwa dengan pendekatan ini loop akan berhenti segera ia menemukan nilai falsey , seperti string kosong, 0, false, NaN, nullatau undefined, bahkan sebelum imencapai panjang, misalnya: jsfiddle.net/prvzk/1
CMS
3
Kondisi loop bisa (item=someArray[i]) !== undefined.
daniel1426
18

Ada metode untuk beralih hanya pada properti objek sendiri, tidak termasuk yang prototipe:

for (var i in array) if (array.hasOwnProperty(i)) {
    // Do something with array[i]
}

tetapi masih akan beralih di atas properti yang ditentukan khusus.

Dalam JavaScript, properti kustom apa pun dapat ditetapkan ke objek apa pun, termasuk larik.

Jika seseorang ingin beralih pada array yang jarang, for (var i = 0; i < array.length; i++) if (i in array)atau array.forEachdengan es5shimharus digunakan.

Kirilloid
sumber
Dan bagaimana kalau menggunakan for (var i in array) if (++i)?
Daniel Sokolowski
15

Ada beberapa cara untuk melakukannya dalam JavaScript. Dua contoh pertama adalah sampel JavaScript. Yang ketiga memanfaatkan perpustakaan JavaScript, yaitu, jQuery memanfaatkan .each()fungsi.

var myStringArray = ["hello", "World"];
for(var i in myStringArray) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
for (var i=0; i < myStringArray.length; i++) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
$.each(myStringArray, function(index, value){
  alert(value);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Shubham Khatri
sumber
for...inharus dihindari untuk objek seperti Array
brk
15

Cara paling elegan dan cepat

var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
    value + 1
}

http://jsperf.com/native-loop-performance/8


Diedit (karena saya salah)


Membandingkan metode untuk pengulangan melalui array 100000 item dan melakukan operasi minimal dengan nilai baru setiap kali.

Persiapan:

<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        // Fake function with minimal action on the value
        var tmp = 0;
        var process = function(value) {
            tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
        };

        // Declare the test Array
        var arr = [];
        for (var i = 0; i < 100000; i++)
            arr[i] = i;
    };
</script>

Tes:

<a href="http://jsperf.com/native-loop-performance/16" 
   title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>
molokoloco
sumber
Putaran ini tampaknya tidak mengikuti urutan item dalam array.
Deniz Ozger
Tes saya salah. Itu benar, menunjukkan semua LOOPS sekarang. jsperf.com/native-loop-performance/16
molokoloco
@bergi benar. Loop ini menghapus array saat loop melalui itu. Tidak seperti yang Anda inginkan dalam banyak kasus.
Stijn de Witt
4
istirahat pada item falsey.
njzk2
12

Pendekatan yang dioptimalkan adalah untuk cache panjang array dan menggunakan pola var tunggal menginisialisasi semua variabel dengan kata kunci var tunggal.

var i, max, myStringArray = ["Hello","World"];
for (i = 0, max = myStringArray.length; i < max; i++) {
    alert(myStringArray[i]);
   //Do something
}

Jika urutan iterasi tidak masalah daripada Anda harus mencoba loop terbalik, ini paling cepat karena mengurangi pengujian kondisi overhead dan penurunan dalam satu pernyataan:

var i,myStringArray = ["item1","item2"];
for (i =  myStringArray.length; i--) {
    alert(myStringArray[i]);
}

atau lebih baik dan lebih bersih untuk digunakan saat loop:

var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
   // do something with fruits[i]
}
Zaheer Ahmed
sumber
12

Dalam JavaScript, ada begitu banyak solusi untuk mengulang array.

Kode di bawah ini adalah yang populer

/** Declare inputs */
const items = ['Hello', 'World']

/** Solution 1. Simple for */
console.log('solution 1. simple for')

for (let i = 0; i < items.length; i++) {
  console.log(items[i])
}

console.log()
console.log()

/** Solution 2. Simple while */
console.log('solution 2. simple while')

let i = 0
while (i < items.length) {
  console.log(items[i++])
}

console.log()
console.log()

/** Solution 3. forEach*/
console.log('solution 3. forEach')

items.forEach(item => {
  console.log(item)
})

console.log()
console.log()

/** Solution 4. for-of*/
console.log('solution 4. for-of')

for (const item of items) {
  console.log(item)
}

console.log()
console.log()

Alongkorn Chetasumon
sumber
12

Jika Anda ingin menggunakan jQuery, ada contoh yang bagus dalam dokumentasinya:

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });
jj_
sumber
12

Cara terbaik menurut saya adalah menggunakan fungsi Array.forEach. Jika Anda tidak dapat menggunakannya saya akan menyarankan untuk mendapatkan polyfill dari MDN. Untuk membuatnya tersedia, ini tentu saja merupakan cara teraman untuk beralih dari sebuah array dalam JavaScript.

Array.prototype.forEach ()

Jadi seperti yang disarankan orang lain, ini hampir selalu seperti yang Anda inginkan:

var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
  sum += n;
});

Ini memastikan bahwa apa pun yang Anda butuhkan dalam lingkup pemrosesan array tetap berada dalam lingkup itu, dan bahwa Anda hanya memproses nilai-nilai array, bukan properti objek dan anggota lainnya, yang merupakan apa yang for ..dilakukan.

Menggunakan forloop gaya-C yang biasa berfungsi dalam banyak kasus. Penting untuk diingat bahwa segala sesuatu di dalam loop membagikan cakupannya dengan program Anda yang lain, {} tidak membuat lingkup baru.

Karenanya:

var sum = 0;
var numbers = [1,11,22,33,44,55,66,77,88,99,111];

for(var i = 0; i<numbers.length; ++i){
  sum += numbers[i];
}

alert(i);

akan menampilkan "11" - yang mungkin atau mungkin tidak seperti yang Anda inginkan.

Contoh jsFiddle yang berfungsi: https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/

Espen
sumber
10

Ini tidak 100% identik, tetapi serupa:

   var myStringArray = ['Hello', 'World']; // array uses [] not {}
    for (var i in myStringArray) {
        console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
    }

Muhammad Alvin
sumber
1
Tampaknya ini akan berhadapan dengan masalah yang sama seperti yang lain dalam penggunaan dengan objek array, dalam variabel anggota prototipe akan ditangkap oleh untuk di juga.
Kzqai
9

Misalnya, saya digunakan di konsol Firefox:

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})
victorq10
sumber
9
var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

Jauh lebih bersih ...

staticd
sumber
Itu tidak terlalu bersih dibandingkan dengan z.forEach(j => console.log(j));.
Sapphire_Brick
9

Jawaban singkat: ya. Anda dapat melakukannya dengan ini:

var myArray = ["element1", "element2", "element3", "element4"];

for (i = 0; i < myArray.length; i++) {
  console.log(myArray[i]);
}

Di konsol browser, Anda dapat melihat sesuatu seperti "element1", "element2", dll., Dicetak.

Juanjo Salvador
sumber
9

Anda dapat menggunakan Array.prototype.forEach(...):

var arr = ["apple", "banana", "cherry", "mango"];
arr.forEach((item, index)=>{
   //Some code...
});

Atau Array.prototype.map(...):

var arr = ["apple", "banana", "cherry", "mango"];
arr.map((item, index)=>{
   //Some code...
});

Atau jquery atau untuk cara loop yang disebutkan sebelumnya.

Sapphire_Brick
sumber