Sirkuit pendek Array.forEach seperti memanggil istirahat

[1,2,3].forEach(function(el) {
    if(el === 1) break;
});

Bagaimana saya bisa melakukan ini menggunakan baru forEach metode dalam JavaScript? I've mencoba kembali;, return false; dan istirahat. istirahat crash dan kembali tidak apa-apa tapi terus iterasi.

Mengomentari pertanyaan (2)
Larutan

Ada's tidak ada built-in kemampuan untuk istirahat di forEach. Untuk mengganggu eksekusi anda akan memiliki untuk melemparkan pengecualian dari beberapa macam. misalnya.

var BreakException = {};

try {
  [1, 2, 3].forEach(function(el) {
    console.log(el);
    if (el === 2) throw BreakException;
  });
} catch (e) {
  if (e !== BreakException) throw e;
}

JavaScript pengecualian aren't sangat cantik. Tradisional untuk loop mungkin akan lebih tepat jika anda benar-benar perlu untuk istirahat di dalamnya.

Gunakan Array#beberapa

Sebaliknya, gunakan Array#beberapa:

[1, 2, 3].some(function(el) {
  console.log(el);
  return el === 2;
});

Ini bekerja karena beberapa mengembalikan true secepat apapun dari callback, yang dilaksanakan di hotel order, kembali benar, hubungan arus pendek eksekusi sisanya.

beberapa, yang invers setiap (yang akan berhenti pada return false), dan forEach semua ECMAScript Edisi Kelima metode yang akan perlu untuk ditambahkan ke Array.prototipe pada browser mana mereka're hilang.

Komentar (14)

Sekarang ada cara yang lebih baik untuk melakukan hal ini di ECMAScript2015 (alias ES6) menggunakan untuk loop. Misalnya, kode ini tidak mencetak elemen array setelah nomor 5:

let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let el of arr) {
  console.log(el);
  if (el === 5) {
    break;
  }
}

Dari docs:

Kedua untuk...di dan untuk...dari pernyataan iterate atas sesuatu. Perbedaan utama antara mereka adalah apa yang mereka iterate atas. The untuk...di pernyataan iterates atas enumerable sifat dari sebuah objek, dalam asli penyisipan order. The untuk...dari pernyataan iterates atas data yang iterable mendefinisikan objek yang akan diiterasi atas.

Perlu indeks dalam iterasi? Anda dapat menggunakan Array.entri():

for (const [index, el] of arr.entries()) {
  if ( index === 5 ) break;
}
Komentar (6)

Anda dapat menggunakan setiap metode:

[1,2,3].every(function(el) {
    return !(el === 1);
});

ES6

[1,2,3].every( el => el !== 1 )

untuk browser lama mendukung penggunaan:

if (!Array.prototype.every)
{
  Array.prototype.every = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          !fun.call(thisp, this[i], i, this))
        return false;
    }

    return true;
  };
}

rincian lebih lanjut di sini.

Komentar (5)

Mengutip dari MDN dokumentasiArray.prototype.forEach():

Ada tidak ada cara untuk berhenti atau istirahat a forEach() loop lain dari dengan melemparkan pengecualian. Jika anda membutuhkan perilaku seperti ini,.forEach() metode ini adalah salah alat, gunakan plain loop sebaliknya. Jika anda sedang menguji elemen array untuk predikat dan perlu mengembalikan nilai boolean, anda dapat menggunakan setiap() atau c() sebagai gantinya.

Untuk kode anda (pertanyaan), seperti yang disarankan oleh @bobince, menggunakan Array.prototype.some() sebagai gantinya. Cocok sangat baik untuk anda usecase.

Array.prototipe.beberapa() mengeksekusi fungsi callback sekali untuk setiap elemen ada dalam array sampai menemukan salah satu di mana callback kembali truthy nilai (nilai yang menjadi kenyataan ketika dikonversi ke Boolean). Jika sebuah elemen tersebut ditemukan, c() segera mengembalikan nilai true. Jika tidak, c() mengembalikan false. callback dipanggil hanya untuk indeks dari array yang telah ditetapkan dengan nilai-nilai; hal ini tidak dipanggil untuk indeks yang telah dihapus atau yang belum pernah diberikan nilai.

Komentar (1)

Sayangnya dalam hal ini akan jauh lebih baik jika anda don't menggunakan forEach. Bukannya menggunakan regular untuk loop dan sekarang akan bekerja persis seperti yang anda harapkan.

var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
  if (array[i] === 1){
    break;
  }
}
Komentar (3)

Pertimbangkan untuk menggunakan jquery's masing-masing metode, karena memungkinkan untuk kembali palsu dalam fungsi callback:

$.each(function(e, i) { 
   if (i % 2) return false;
   console.log(e)
})

Lodash perpustakaan juga menyediakan takeWhile metode yang dapat dirantai dengan peta/mengurangi/lipat dll:

var users = [
  { 'user': 'barney',  'active': false },
  { 'user': 'fred',    'active': false },
  { 'user': 'pebbles', 'active': true }
];

_.takeWhile(users, function(o) { return !o.active; });
// => objects for ['barney', 'fred']

// The `_.matches` iteratee shorthand.
_.takeWhile(users, { 'user': 'barney', 'active': false });
// => objects for ['barney']

// The `_.matchesProperty` iteratee shorthand.
_.takeWhile(users, ['active', false]);
// => objects for ['barney', 'fred']

// The `_.property` iteratee shorthand.
_.takeWhile(users, 'active');
// => []
Komentar (3)

Dari contoh kode, sepertinya Array.prototipe.menemukan adalah apa yang anda cari adalah: Array.prototipe.menemukan() dan Array.prototipe.findIndex()

[1, 2, 3].find(function(el) {
    return el === 2;
}); // returns 2
Komentar (0)

Jika anda ingin menggunakan Dean Edward's saran dan membuang StopIteration kesalahan untuk keluar dari loop tanpa harus menangkap kesalahan, anda dapat menggunakan berikut fungsi (awalnya dari sini):

// Use a closure to prevent the global namespace from be polluted.
(function() {
  // Define StopIteration as part of the global scope if it
  // isn't already defined.
  if(typeof StopIteration == "undefined") {
    StopIteration = new Error("StopIteration");
  }

  // The original version of Array.prototype.forEach.
  var oldForEach = Array.prototype.forEach;

  // If forEach actually exists, define forEach so you can
  // break out of it by throwing StopIteration.  Allow
  // other errors will be thrown as normal.
  if(oldForEach) {
    Array.prototype.forEach = function() {
      try {
        oldForEach.apply(this, [].slice.call(arguments, 0));
      }
      catch(e) {
        if(e !== StopIteration) {
          throw e;
        }
      }
    };
  }
})();

Kode di atas akan memberikan anda kemampuan untuk menjalankan kode seperti berikut tanpa harus melakukan anda sendiri try-catch klausa:

// Show the contents until you get to "2".
[0,1,2,3,4].forEach(function(val) {
  if(val == 2)
    throw StopIteration;
  alert(val);
});

Salah satu hal yang penting untuk diingat adalah bahwa ini hanya akan update Array.prototipe.forEach fungsi jika sudah ada. Jika itu doesn't sudah ada, itu tidak akan mengubah itu.

Komentar (0)

Jawaban singkat: gunakan untuk...istirahat untuk ini atau mengubah kode anda untuk menghindari melanggar forEach. Jangan gunakan .beberapa() atau .setiap() meniru untuk...istirahat. Menulis ulang kode untuk menghindari untuk...istirahat loop, atau menggunakan untuk...istirahat. Setiap kali anda menggunakan metode ini sebagai untuk...istirahat alternatif Allah membunuh anak kucing.

Jawaban panjang:

.beberapa() dan .setiap() kembali boolean nilai .beberapa() mengembalikan true jika ada elemen yang berlalu fungsi mengembalikan true, setiap kembali palsu jika ada elemen yang berlalu kembali fungsi palsu. Ini adalah apa itu fungsi yang berarti. Menggunakan fungsi-fungsi untuk apa yang mereka doesn't maksud adalah jauh lebih buruk kemudian menggunakan tabel untuk layout bukannya CSS, karena sepertinya semua orang yang membaca kode anda.

Juga, satu-satunya cara yang mungkin untuk menggunakan metode ini sebagai untuk...istirahat alternatif adalah untuk membuat efek-samping (mengubah beberapa vars luar .beberapa() fungsi callback), dan hal ini tidak jauh berbeda dari untuk...istirahat.

Jadi, dengan menggunakan .beberapa() atau .setiap() sebagai untuk...istirahat loop alternatif isn't bebas dari efek samping, ini isn't jauh lebih bersih kemudian untuk...istirahat, ini adalah frustasi, jadi ini isn't lebih baik.

Anda selalu dapat menulis ulang kode anda sehingga tidak akan ada perlu di untuk...istirahat. Anda dapat menyaring menggunakan array .filter(), anda dapat membagi array menggunakan .slice() dan sebagainya, maka gunakan .forEach() atau .peta() untuk itu bagian dari array.

Komentar (4)

Ditemukan solusi ini pada situs lain. Anda dapat membungkus forEach di coba / tangkap skenario.

if(typeof StopIteration == "undefined") {
 StopIteration = new Error("StopIteration");
}

try {
  [1,2,3].forEach(function(el){
    alert(el);
    if(el === 1) throw StopIteration;
  });
} catch(error) { if(error != StopIteration) throw error; }

Rincian lebih lanjut di sini: http://dean.edwards.name/weblog/2006/07/enum/

Komentar (1)

Ini hanya sesuatu yang saya datang dengan untuk memecahkan masalah... saya'm cukup yakin ini perbaikan masalah yang asli penanya telah:


Array.prototype.each = function(callback){
    if(!callback) return false;
    for(var i=0; i
Komentar (1)

Konsep lain yang saya datang dengan:

function forEach(array, cb) {
  var shouldBreak;
  function _break() { shouldBreak = true; }
  for (var i = 0, bound = array.length; i < bound; ++i) {
    if (shouldBreak) { break; }
    cb(array[i], i, array, _break);
  }
}

// Usage

forEach(['a','b','c','d','e','f'], function (char, i, array, _break) {
  console.log(i, char);
  if (i === 2) { _break(); }
});
Komentar (4)

Jika anda don't perlu untuk mengakses array setelah iterasi anda dapat bail out oleh pengaturan array's suhu udara turun menjadi 0. Jika anda masih membutuhkannya setelah iterasi anda bisa clone menggunakan slice..

[1,3,4,5,6,7,8,244,3,5,2].forEach(function (item, index, arr) {
  if (index === 3) arr.length = 0;
});

Atau dengan clone:

var x = [1,3,4,5,6,7,8,244,3,5,2];

x.slice().forEach(function (item, index, arr) {
  if (index === 3) arr.length = 0;
});

Yang merupakan solusi yang jauh lebih baik kemudian melemparkan kesalahan acak dalam kode anda.

Komentar (1)

Ini adalah untuk loop, tapi mempertahankan referensi objek dalam lingkaran seperti forEach() tapi anda bisa keluar.

var arr = [1,2,3];
for (var i = 0, el; el = arr[i]; i++) {
    if(el === 1) break;
}
Komentar (0)

Seperti disebutkan sebelumnya, anda dapat't break .forEach().

Berikut ini's yang sedikit lebih modern cara melakukan foreach dengan ES6 Iterator. Memungkinkan anda untuk mendapatkan akses langsung ke index/nilai ketika iterasi.

const array = ['one', 'two', 'three'];

for (const [index, val] of array.entries()) {
  console.log('item:', { index, val });
  if (index === 1) {
    console.log('break!');
    break;
  }
}

Output:

item: { index: 0, val: 'one' }
item: { index: 1, val: 'two' }
break!

Link

Komentar (0)

Saya menggunakan nullhack untuk tujuan itu, ia mencoba untuk mengakses properti dari nol, yang merupakan kesalahan:

try {
  [1,2,3,4,5]
  .forEach(
    function ( val, idx, arr ) {
      if ( val == 3 ) null.NULLBREAK;
    }
  );
} catch (e) {
  // e  TypeError: null has no properties
}
//
Komentar (1)

Aku tahu itu bukan cara yang tepat. Hal ini tidak mematahkan lingkaran. Ini adalah Jugad

let result = true;
[1, 2, 3].forEach(function(el) {
    if(result){
      console.log(el);
      if (el === 2){
        result = false;
      }
    }
});
Komentar (0)

Jika anda ingin menyimpan forEach sintaks, ini adalah cara untuk tetap efisien (meskipun tidak sebagus biasa untuk loop). Cek segera untuk variabel yang tahu jika anda ingin keluar dari loop.

Contoh ini menggunakan fungsi anonim untuk menciptakan ruang lingkup fungsi sekitar forEach yang anda butuhkan untuk menyimpan melakukan informasi.

(function(){
    var element = document.getElementById('printed-result');
    var done = false;
    [1,2,3,4].forEach(function(item){
        if(done){ return; }
        var text = document.createTextNode(item);
        element.appendChild(text);
        if (item === 2){
          done = true;
          return;
        }
    });
})();
<div id="printed-result"></div>

Saya dua sen.

Komentar (0)

Namun pendekatan lain

        var wageType = types.filter(function(element){
            if(e.params.data.text == element.name){ 
                return element;
            }
        });
        console.dir(wageType);
Komentar (0)

Gunakan array.prototipe.setiap fungsi, yang menyediakan utilitas untuk memecahkan perulangan. Lihat contoh berikut ini Javascript dokumentasi di Mozilla developer network

Komentar (0)