Pertanyaan Loop melalui larik dalam JavaScript


Di Jawa Anda bisa menggunakan for loop ke objek lintasan dalam larik sebagai berikut:

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

Bisakah Anda melakukan hal yang sama dalam JavaScript?


2415
2018-06-10 00:04


asal


Jawaban:


Gunakan sekuensial for lingkaran:

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

@zipcodeman menyarankan penggunaan for...in pernyataan, tetapi untuk susunan berurutan for-in harus dihindari, pernyataan itu dimaksudkan untuk menghitung properti objek.

Tidak boleh digunakan untuk objek seperti larik karena:

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

Poin kedua adalah bahwa hal itu dapat memberi Anda banyak masalah, misalnya, jika Anda memperpanjang Array.prototype objek 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) {
  alert(array[i]);
}

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

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

Itu for-in pernyataan seperti yang saya katakan sebelumnya ada untuk menghitung properti objek, 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...
    alert("prop: " + prop + " value: " + obj[prop])
  }
}

Dalam contoh di atas, hasOwnProperty metode memungkinkan Anda untuk menghitung saja memiliki properti sendiri, hanya itu, hanya properti yang dimiliki objek secara fisik, tidak ada properti yang diwariskan.

Saya akan merekomendasikan Anda untuk membaca artikel berikut:


3050
2018-06-10 00:07



Ya, tetapi hanya jika penerapan Anda termasuk for...of fitur yang diperkenalkan di ECMAScript 2015 (Rilis "Harmony").

Ia bekerja 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-cakupan melalui let dan const:

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

Banyak pengembang JavaScript masih bekerja di lingkungan yang belum ada di sana, namun - terutama jika menulis kode untuk dijalankan di browser web, di mana pengembang situs sering tidak dapat memastikan browser / versi apa yang akan digunakan klien mereka.

Jika Anda dapat menganggap juru bahasa JavaScript sesuai dengan sebelumnya edisi spesifikasi ECMAScript (yang mengesampingkan, misalnya, versi Internet Explorer sebelum 9), maka Anda dapat menggunakan forEach metode iterator bukan loop. Dalam hal ini, Anda melewatkan fungsi untuk dipanggil pada setiap item dalam larik:

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

Tetapi jika itu terlalu banyak untuk diasumsikan, dan Anda menginginkan sesuatu yang berhasil semua versi JavaScript, maka Anda harus menggunakan loop penghitungan yang eksplisit. Versi paling aman, yang menangani array yang jarang dengan benar, adalah sesuatu seperti ini:

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 (bukan termasuk yang lengkap myStringArray.length ekspresi dalam kondisi loop) dapat membuat perbedaan kinerja yang signifikan karena melewatkan pencarian properti setiap kali melalui; menggunakan Rhino di mesin saya, kecepatannya 43%.

Anda akan sering melihat panjang caching yang dilakukan dalam klausa inisialisasi loop, seperti ini:

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

Itu for...in sintaks yang disebutkan oleh orang lain adalah untuk mengulang di atas properti suatu objek; karena Array dalam JavaScript hanyalah sebuah objek dengan nama properti numerik (dan diperbarui secara otomatis lengthproperti), Anda dapat secara teoritis menggilir Array dengannya. Tapi masalahnya adalah bahwa itu tidak membatasi diri ke nilai properti numerik (ingat bahwa bahkan metode sebenarnya hanyalah properti yang nilainya adalah penutupan), juga bukan iterate atas mereka dalam urutan numerik. Oleh karena itu, for...in sintaks seharusnya tidak digunakan untuk perulangan melalui Array.


868
2018-04-16 02:03



Kamu dapat memakai 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 func akan 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.map adalah larik lainnya, jadi 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 perlu menulis fungsi inline. Itu bisa menjadi 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.


391
2018-06-10 00:09



Dalam JavaScript, Anda tidak disarankan untuk mengulang melalui Array dengan for-in loop, tetapi lebih baik menggunakan for loop, 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.


102
2017-12-07 07:24



for (var s of myStringArray) {

(Langsung menjawab pertanyaan Anda: sekarang Anda bisa!)

Sebagian besar jawaban lainnya benar, tetapi mereka tidak menyebutkan (seperti tulisan ini) itu Script ECMA 6 2015 membawa mekanisme baru untuk melakukan iterasi, for..of lingkaran.

Sintaks baru ini adalah cara paling elegan untuk mengulang array dalam javascript (selama Anda tidak membutuhkan indeks iterasi), tetapi belum didukung secara luas oleh browser.

Saat ini berfungsi dengan Firefox 13+, Chrome 37+ dan tidak bekerja dengan browser lain (lihat kompatibilitas browser di bawah). Untungnya kami memiliki compiler JS (seperti Babel) yang memungkinkan kita untuk menggunakan fitur generasi selanjutnya 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 suatu array 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 diambil 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

}


92
2017-08-11 15:54



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

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

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

menyaring mengembalikan serangkaian item yang memenuhi beberapa kondisi atau pengujian.

setiap mengembalikan nilai true jika setiap anggota array lulus tes.

beberapa mengembalikan nilai true jika lulus tes.

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

peta seperti forEach, tetapi mengembalikan larik hasil operasi untuk setiap elemen.

Semua metode ini mengambil fungsi untuk argumen pertama mereka dan memiliki argumen kedua opsional, yang merupakan objek yang lingkupnya ingin Anda terapkan pada anggota array saat mereka mengulang melalui fungsi.

Abaikan sampai Anda membutuhkannya.

Indeks dan lastIndexOf temukan posisi yang sesuai dari elemen pertama atau terakhir yang cocok dengan argumennya secara tepat.

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

81
2018-06-10 02:43



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 yang klasik for lingkaran

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/


62
2018-01-05 09:15



Intro

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

Sementara mereka semua memiliki keistimewaan linguistik masing-masing, masing-masing bahasa ini berbagi banyak konsep dasar yang sama. Konsep-konsep tersebut termasuk prosedur / fungsi, IF-statements, FOR-perasaan, dan WHILE-apa.


Tradisional for-suka

Tradisional for lingkaran memiliki tiga komponen:

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

Ketiga komponen ini dipisahkan satu sama lain oleh a ; simbol. Konten untuk masing-masing dari ketiga komponen ini bersifat opsional, yang berarti yang berikut ini yang paling minim for lingkaran mungkin:

for (;;) {
    // Do stuff
}

Tentu saja, Anda harus menyertakan sebuah if(condition === true) { break; }  atau sebuah if(condition === true) { return; } suatu tempat di dalam itu for-Biarkan sampai berhenti berjalan.

Biasanya, meskipun, inisialisasi digunakan untuk mendeklarasikan indeks, kondisi digunakan untuk membandingkan indeks dengan nilai minimum atau maksimum, dan renungan digunakan untuk kenaikan indeks:

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

Menggunakan tradisional for loop ke 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 memutar ke belakang, Anda melakukan ini:

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

Namun demikian, banyak variasi yang mungkin, seperti contohnya 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);
}

Mana yang paling berhasil adalah masalah selera pribadi dan kasus penggunaan spesifik yang Anda terapkan.

Perhatikan bahwa setiap variasi ini didukung oleh semua browser, termasuk yang sangat sangat tua!


SEBUAH while lingkaran

Salah satu alternatif untuk for loop adalah a whilelingkaran. Untuk mengulang melalui array, Anda bisa melakukan ini:

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

Seperti tradisional for loop, while loop didukung oleh bahkan peramban tertua.

Juga, perhatikan bahwa setiap loop sementara dapat ditulis ulang sebagai for lingkaran. Misalnya, while lingkaran di sini di atas berfungsi dengan cara yang sama seperti ini for-apa:

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

For...in dan for...of

Di JavaScript, Anda juga dapat melakukan ini:

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

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

Sebagai alternatif untuk for...in, sekarang ada juga untuk for...of. Contoh berikut menunjukkan perbedaan antara a for...of loop dan a for...in lingkaran:

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 itu for...in membutuhkan setidaknya Internet Explorer 10.


Array.prototype.forEach()

Sebuah alternatif untuk for- upsops 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 milik mereka sendiri foreach variasi. 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);
});

48
2018-02-29 18:56



Jika Anda ingin cara singkat untuk menulis loop cepat dan Anda dapat melakukan iterasi secara terbalik:

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

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

Bahkan ada beberapa kali ketika Anda harus beralih secara terbalik, seperti ketika iterasi lebih dari a tinggal NodeList di mana Anda berencana untuk menghapus item dari DOM selama iterasi.


35
2018-06-04 16:26