Cortocircuito Array.forEach como llamar a break

Resuelto Scott Klarenbach asked hace 14 años • 32 respuestas
[1,2,3].forEach(function(el) {
    if(el === 1) break;
});

¿ Cómo puedo hacer esto usando el nuevo forEachmétodo en JavaScript? Lo he return;intentado return false;y break. breakfalla y returnno hace nada más que continuar la iteración.

Scott Klarenbach avatar Apr 15 '10 04:04 Scott Klarenbach
Aceptado

No hay ninguna capacidad incorporada para breakingresar forEach. Para interrumpir la ejecución tendrías que lanzar una excepción de algún tipo. p.ej.

var BreakException = {};

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

Las excepciones de JavaScript no son muy bonitas. Un forbucle tradicional podría ser más apropiado si realmente necesitas breakentrar en él.

UsarArray#some

En su lugar, utilice Array#some:

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

Esto funciona porque someregresa truetan pronto como cualquiera de las devoluciones de llamada, ejecutadas en orden de matriz, regresa true, provocando un cortocircuito en la ejecución del resto.

some, es inverso every(que se detendrá en a return false), y forEachson todos métodos de ECMAScript Quinta Edición que deberán agregarse a los Array.prototypenavegadores donde faltan.

UsarArray#every

[1, 2, 3].every(v => {
  if (v > 2) {
    return false // "break"
  }
  console.log(v);
  return true // must return true if doesn't break
});
Expandir fragmento

bobince avatar Apr 14 '2010 22:04 bobince

Ahora existe una manera aún mejor de hacer esto en ECMAScript2015 (también conocido como ES6) usando el nuevo for of loop . Por ejemplo, este código no imprime los elementos de la matriz después del número 5:

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

De los documentos:

Tanto las declaraciones for...in como for...of se repiten sobre algo. La principal diferencia entre ellos está en lo que iteran. La declaración for...in itera sobre las propiedades enumerables de un objeto, en el orden de inserción original. La declaración for...of itera sobre los datos que el objeto iterable define para iterar.

¿Necesita el índice en la iteración? Puedes usar Array.entries():

for (const [index, el] of arr.entries()) {
  if ( index === 5 ) break;
}
canac avatar Aug 19 '2015 16:08 canac

Puedes utilizar todos los métodos:

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

ES6

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

para uso de soporte de navegador antiguo:

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

más detalles aquí .

Valdemar_Rudolfovich avatar Jul 19 '2012 09:07 Valdemar_Rudolfovich

Citando la documentación de MDN deArray.prototype.forEach() :

No hay otra forma de detener o romper un forEach()bucle que no sea lanzando una excepción. Si necesita ese comportamiento, el .forEach()método es la herramienta incorrecta , utilice un bucle simple en su lugar. Si está probando los elementos de la matriz para un predicado y necesita un valor de retorno booleano, puede usar every()o some()en su lugar.

Para su código (en la pregunta), como lo sugiere @bobince, use Array.prototype.some()en su lugar. Se adapta muy bien a su caso de uso.

Array.prototype.some()ejecuta la función de devolución de llamada una vez para cada elemento presente en la matriz hasta que encuentra uno donde la devolución de llamada devuelve un valor verdadero (un valor que se vuelve verdadero cuando se convierte en a Boolean). Si se encuentra dicho elemento, some()devuelve verdadero inmediatamente. De lo contrario, some()devuelve falso. La devolución de llamada se invoca sólo para los índices de la matriz que tienen valores asignados; no se invoca para índices que se han eliminado o a los que nunca se les han asignado valores.

Rahul Desai avatar Jan 06 '2016 21:01 Rahul Desai

Desafortunadamente, en este caso será mucho mejor si no lo usas forEach. En su lugar, utilice un bucle normal fory ahora funcionará exactamente como cabría esperar.

var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
  if (array[i] === 1){
    break;
  }
}
Weston Ganger avatar Aug 25 '2015 20:08 Weston Ganger

Según su ejemplo de código, parece que Array.prototype.findes lo que está buscando: Array.prototype.find() y Array.prototype.findIndex()

[1, 2, 3].find(function(el) {
    return el === 2;
}); // returns 2
Oliver Moran avatar Jan 15 '2017 20:01 Oliver Moran