¿Cómo detener un bucle JavaScript for?

127

Estoy usando este JavaScript para iterar a través de una matriz y encontrar un elemento de matriz coincidente:

var remSize = [], 
    szString, remData, remIndex, i;

for (i = 0; i < remSize.length; i++) {      
    // I'm looking for the index i, when the condition is true
    remSize[i].size == remData.size ? remIndex = i : remIndex = -1;     
}

La matriz contiene estos "tamaños": ["34", "36", "38"...].

remData.size es el "tamaño" que estoy buscando (por ejemplo, "36").

Necesito devolver el índice isi el tamaño que estoy buscando está en el índice. De lo contrario, tengo que volver -1. ¿Hay una mejor manera de hacer esto?

frecuente
fuente

Respuestas:

193

Para detener un forciclo temprano en JavaScript, usa break:

var remSize = [], 
    szString,
    remData,
    remIndex,
    i;

/* ...I assume there's code here putting entries in `remSize` and assigning something to `remData`... */

remIndex = -1; // Set a default if we don't find it
for (i = 0; i < remSize.length; i++) {      
     // I'm looking for the index i, when the condition is true
     if (remSize[i].size === remData.size) {
          remIndex = i;
          break;       // <=== breaks out of the loop early
     }
}

Si se encuentra en un entorno ES2015 (también conocido como ES6), para este caso de uso específico , puede usar Array#findIndex(para encontrar el índice de la entrada) o Array#find(para encontrar la entrada en sí), los cuales pueden ser calzados / rellenados:

var remSize = [], 
    szString,
    remData,
    remIndex;

/* ...I assume there's code here putting entries in `remSize` and assigning something to `remData`... */

remIndex = remSize.findIndex(function(entry) {
     return entry.size === remData.size;
});

Array#find:

var remSize = [], 
    szString,
    remData,
    remEntry;

/* ...I assume there's code here putting entries in `remSize` and assigning something to `remData`... */

remEntry = remSize.find(function(entry) {
     return entry.size === remData.size;
});

Array#findIndexse detiene la primera vez que la devolución de llamada devuelve un valor verdadero, devolviendo el índice de esa llamada a la devolución de llamada; vuelve -1si la devolución de llamada nunca devuelve un valor verdadero. Array#findtambién se detiene cuando encuentra lo que está buscando, pero devuelve la entrada, no su índice (o undefinedsi la devolución de llamada nunca devuelve un valor verdadero).

Si está utilizando un entorno compatible con ES5 (o una cuña ES5), puede usar la nueva somefunción en matrices, que llama a una devolución de llamada hasta que la devolución de llamada devuelva un valor verdadero:

var remSize = [], 
    szString,
    remData,
    remIndex;

/* ...I assume there's code here putting entries in `remSize` and assigning something to `remData`... */

remIndex = -1; // <== Set a default if we don't find it
remSize.some(function(entry, index) {
    if (entry.size === remData.size) {
        remIndex = index;
        return true; // <== Equivalent of break for `Array#some`
    }
});

Si está usando jQuery, puede usar jQuery.eachpara recorrer una matriz; eso se vería así:

var remSize = [], 
    szString,
    remData,
    remIndex;

/* ...I assume there's code here putting entries in `remSize` and assigning something to `remData`... */

remIndex = -1; // <== Set a default if we don't find it
jQuery.each(remSize, function(index, entry) {
    if (entry.size === remData.size) {
        remIndex = index;
        return false; // <== Equivalent of break for jQuery.each
    }
});
TJ Crowder
fuente
1
El uso de la declaración de devolución es un buen enfoque. Gracias @TJ Crowder
techloris_109
@TJ Crowder, ¿qué afirmación es un buen enfoque: devolver falso o romper?
Ilyas karim
3
@Ilyaskarim: Utiliza el apropiado para la construcción que estás usando ( breaken un forbucle, return falseen jQuery.each, return trueen some, ...).
TJ Crowder
13

Utilice for of loop en su lugar, que forma parte de la versión ES2015. A diferencia de forEach, podemos usar return, break y continue. Ver https://hacks.mozilla.org/2015/04/es6-in-depth-iterators-and-the-for-of-loop/

let arr = [1,2,3,4,5];
for (let ele of arr) {
  if (ele > 3) break;
  console.log(ele);
}
Srini Karthikeyan
fuente
buen uso de es6, creo que esta es una de las mejores respuestas aquí
Emad Salah
De hecho, diría que es LA mejor respuesta aquí, la forma más sencilla de hacerlo ("la sintaxis más concisa y directa hasta ahora para recorrer los elementos de la matriz", como dice Mozilla Hacks en el enlace de la respuesta). Deberíamos pagar todo el trabajo duro que se ha dedicado a ES6 haciendo uso de sus nuevas funciones siempre que podamos (y beneficiarnos en el proceso).
Velojet
10

La lógica es incorrecta. Siempre devolvería el resultado del último elemento en la matriz.

remIndex = -1;

for (i = 0; i < remSize.length; i++) {      
    if (remSize[i].size == remData.size) {
        remIndex = i
        break;
    }
}
amit_g
fuente
0

Sé que esto es un poco viejo, pero en lugar de recorrer la matriz con un ciclo for, sería mucho más fácil usar el método <array>.indexOf(<element>[, fromIndex])

Recorre una matriz, encuentra y devuelve el primer índice de un valor. Si el valor no está contenido en la matriz, devuelve -1.

<array>es la matriz a mirar, <element>es el valor que está buscando y [fromIndex]es el índice desde el cual comenzar (el valor predeterminado es 0).

¡Espero que esto ayude a reducir el tamaño de su código!

JMoore2007
fuente
1
Esto no responde a la pregunta del título: How to stop a JavaScript for loop?Se hace la respuesta ¿Hay una mejor manera de devolver el índice de un partido / -1 si ninguno .
barba gris el