Scurt-circuit Matrice.forEach cum ar fi de asteptare rupe

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

Cum pot face acest lucru folosind noul "forEach" metoda în JavaScript? Am'am încercat revenirea lui;,return false; "" și "pauză". "rupe" de accidente și "întoarcere" nu face nimic, dar continua repetare.

Comentarii la întrebare (2)
Soluția

Nu's built-in capacitatea de a "sparge" în "forEach". Pentru a întrerupe executarea ar trebui să arunca o excepție de un anumit fel. de exemplu.

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 excepții sunt't teribil de frumos. Un tradițional "pentru" bucla ar putea fi mai potrivit, dacă aveți cu adevărat nevoie de a "rupe" în interiorul acestuia.

Utilizare Matrice#unele

În schimb, utilizați Matrice#unele:

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

Acest lucru funcționează pentru că "unele" returnează "adevărat" de indata ce oricare dintre callback, executată în array comanda, returnează "adevărat", scurt-circuit executarea de restul.

"unele", își inverse fiecare (care se va opri pe o return false), și "forEach" sunt toate ECMAScript de-a Cincea Ediție a metodelor care vor trebui să fie adăugate la `Matrice.prototip pe browsere de unde au're lipsește.

Comentarii (14)

Există acum o modalitate mai bună de a face acest lucru în ECMAScript2015 (aka ES6) folosind noua pentru a buclei. De exemplu, acest cod nu imprimați elementele de matrice după numărul 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;
  }
}

Din documente:

Ambele în și pentru...de declarații repeta peste ceva. Principala diferență dintre ele este în ceea ce se repeta peste. La în declarația reiterează peste nenumărate proprietăți ale unui obiect, în original inserție ordine. La pentru...de declarația reiterează peste datele care iterable obiect definește a fi reiterat peste.

Trebuie indicelui în repetare? Puteți utiliza Matrice.intrări():

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

Puteți utiliza fiecare metoda:

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

ES6

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

pentru vechi sprijin browser-ul folosit:

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

mai multe detalii aici.

Comentarii (5)

Citez din MDN documentația deArray.prototype.forEach():

nu Există nici o modalitate de a opri sau de a sparge o forEach() bucla, altele decât de a arunca o excepție. Dacă aveți nevoie de astfel de comportament,.forEach() metoda este greșit instrument de, utilizați un simplu buclă în loc. Dacă sunteți de testare elementele de matrice pentru un predicat și au nevoie de un boolean valoarea de returnare, puteți utiliza fiecare() sau un() în loc.

Pentru cod (în cauză), după cum a sugerat @bobince, utilizare Array.prototype.some() în loc. Se potriveste foarte bine la usecase.

Matrice.prototip.unele() execută funcția de apel invers o singură dată pentru fiecare element prezent în gamă până când se găsește unul care callback returnează o sinceră valoare (o valoare care devine realitate atunci când sunt convertite la un "Boolean"). Dacă un astfel de element este găsit, pentru unele()returnează imediat adevărat. În caz contrar,un()` întoarce false. callback este apelată numai pentru indici din matrice care au atribuit valori; nu este invocat pentru indici care au fost șterse sau care nu au fost atribuite valori.

Comentarii (1)

Din păcate, în acest caz, acesta va fi mult mai bine dacă tu nu't folosi "forEach". În loc să folosească un "pentru" buclă și va funcționa exact așa cum v-ați aștepta.

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

Ia în considerare pentru a utiliza "jquery" 's fiecare metoda, deoarece permite să se întoarcă false în interiorul funcție de apel invers:

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

Lodash biblioteci oferă, de asemenea, takeWhile metoda care poate fi legat cu map/reduce/ori etc:

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');
// => []
Comentarii (3)

Din exemplu de cod, se pare ca `Matrice.prototip.găsi ceea ce căutați pentru: Matrice.prototip.find() și Matrice.prototip.findIndex()

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

Dacă doriți să utilizați Dean Edward's sugestie si arunca StopIteration eroare pentru a iesi din bucla fără a fi nevoie pentru a prinde de eroare, puteți folosi următoarea funcție (inițial de aici):

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

Codul de mai sus va oferi posibilitatea de a rula cod, cum ar fi următoarele, fără a fi nevoie să-ți faci propriul try-catch clauze:

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

Un lucru important de reținut este faptul că acest lucru va actualiza numai Matrice.prototip.forEach funcție, dacă acesta există deja. Dacă nu't există deja, acesta nu va modifica-l.

Comentarii (0)

Răspuns scurt: utilizați pentru...rupepentru acest lucru sau să modificați codul pentru a evita ruperea de "forEach". A nu se folosi.unele (de) "sau".fiecare()să se întreacă pentru...rupe. Rescrie codul pentru a evita pentru...rupe bucla, sau de a folosi pentru...rupe. De fiecare dată când utilizați aceste metode ca pentru...rupe alternative Dumnezeu ucide pisica.

Răspuns lung:

.unele () "și".fiecare() reveni boolean valoare .unele() returnează "true" dacă există orice element pentru care au trecut funcția returnează "adevărat", fiecare se întoarce "fals" dacă nu există nici un element care a trecut funcția returnează "false". Aceasta este ceea ce că funcțiile. Utilizarea funcțiilor pentru ceea ce ei nu't să spun este mult mai rău atunci folosind tabele pentru layout în loc de CSS, pentru că-l enervează pe toată lumea care citește codul.

De asemenea, singurul mod posibil de a utiliza aceste metode pentru...rupealternativă este de a face efecte secundare (schimba unele vars în afara.unele()callback function), iar acest lucru nu este cu mult diferit de lapentru...rupe`.

Deci, folosind .unele (de) "sau".fiecare () " ca " pentru...rupe bucla alternativă e't lipsite de efecte secundare, e't mult mai curat atunci pentru...rupe`, acest lucru este frustrant, așa că nu e't mai bine.

Întotdeauna poți rescrie codul dvs., astfel încât nu va mai fi nevoie în pentru...rupe. Puteți filtra matrice folosind .filtru(), puteți împărți matrice folosind .slice() și așa mai departe, apoi utilizați .forEach () "sau".harta() pentru că o parte din matrice.

Comentarii (4)

A găsit această soluție pe un alt site. Puteți încheia forEach într-un try / catch scenariu.

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

Mai multe detalii aici: http://dean.edwards.name/weblog/2006/07/enum/

Comentarii (1)

Acest lucru este doar ceva cu care am venit pentru a rezolva problema... m-am'm destul de sigur că rezolvă problema că originalul asker avut:


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

Un alt concept am venit cu:

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

Dacă tu nu't nevoie pentru a accesa matrice după repetare puteți salva prin stabilirea matrice's lungimea la 0. Dacă încă nevoie de ea după repetare ai putea clona folosind felie..

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

Sau cu o clona:

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

Care este o soluție mult mai bine apoi a aruncat aleatoare erori în cod.

Comentarii (1)

Aceasta este o buclă, dar menține obiectul de referință în buclă ca un forEach (), dar puteți ieși.

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

Așa cum am menționat înainte, puteți't rupe .forEach().

Aici's un pic mai modern mod de a face un foreach cu ES6 Iteratori. Vă permite să obțineți acces direct la "index" / "valoare" atunci când iterarea.

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

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

Ieșire:

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

Link-uri

Comentarii (0)

Eu folosesc nullhack pentru acest scop, ea încearcă să acceseze proprietatea null, care este o eroare:

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

Știu că nu-i corect mod. Nu se rupe bucla. Este un Jugad

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

Dacă vrei să-ți păstrezi "forEach" sintaxa, aceasta este o modalitate de a păstra eficient (deși nu la fel de bun ca un regulat pentru bucla). Verificați imediat pentru o variabilă care știe că, dacă vrei să ieși din bucla.

Acest exemplu utilizează o funcție anonim pentru a crea o funcție de domeniul de aplicare în jur de "forEach" care aveți nevoie pentru a stoca făcut informații.

(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>

Cei doi cenți ai mei.

Comentarii (0)

O altă abordare

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

Folosi `matrice.prototip.fiecare funcția, care vă oferă utilitatea de a sparge looping. Vezi de exemplu aici Javascript documentația pe Mozilla developer network

Comentarii (0)