que - ¿La mejor manera de romper los bucles anidados en Javascript?
iteraciones anidadas (13)
¿Qué hay de usar sin interrupciones, sin indicadores de cancelación y sin controles de condición adicionales? Esta versión simplemente destruye las variables de bucle (las convierte en Number.MAX_VALUE
) cuando se cumple la condición y obliga a todos los bucles a terminar de manera elegante.
// No breaks needed
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (condition) {
console.log("condition met");
i = j = Number.MAX_VALUE; // Blast the loop variables
}
}
}
Hubo una respuesta similar para los bucles anidados de tipo decremento, pero esto funciona para los bucles anidados de tipo incremental sin necesidad de considerar el valor de terminación de cada bucle para los bucles simples.
Otro ejemplo:
// No breaks needed
for (var i = 0; i < 89; i++) {
for (var j = 0; j < 1002; j++) {
for (var k = 0; k < 16; k++) {
for (var l = 0; l < 2382; l++) {
if (condition) {
console.log("condition met");
i = j = k = l = Number.MAX_VALUE; // Blast the loop variables
}
}
}
}
}
¿Cuál es la mejor manera de romper los bucles anidados en Javascript?
//Write the links to the page.
for (var x = 0; x < Args.length; x++)
{
for (var Heading in Navigation.Headings)
{
for (var Item in Navigation.Headings[Heading])
{
if (Args[x] == Navigation.Headings[Heading][Item].Name)
{
document.write("<a href=/""
+ Navigation.Headings[Heading][Item].URL + "/">"
+ Navigation.Headings[Heading][Item].Name + "</a> : ");
break; // <---HERE, I need to break out of two loops.
}
}
}
}
¿Qué tal empujar los bucles a sus límites finales?
for(var a=0; a<data_a.length; a++){
for(var b=0; b<data_b.length; b++){
for(var c=0; c<data_c.length; c++){
for(var d=0; d<data_d.length; d++){
a = data_a.length;
b = data_b.length;
c = data_b.length;
d = data_d.length;
}
}
}
}
Al igual que Perl,
loop1:
for (var i in set1) {
loop2:
for (var j in set2) {
loop3:
for (var k in set3) {
break loop2; // breaks out of loop3 and loop2
}
}
}
como se define en EMCA-262 sección 12.12. [MDN Docs]
A diferencia de C, estas etiquetas solo se pueden usar para continue
y break
, ya que Javascript no tiene goto
.
Envuelva eso en una función y luego simplemente return
.
Llego un poco tarde a la fiesta, pero el siguiente es un enfoque independiente del lenguaje que no usa GOTO / labels o función de ajuste:
for (var x = Set1.length; x > 0; x--)
{
for (var y = Set2.length; y > 0; y--)
{
for (var z = Set3.length; z > 0; z--)
{
z = y = -1; // terminates second loop
// z = y = x = -1; // terminate first loop
}
}
}
Por el lado positivo, fluye naturalmente, lo que debería complacer a la gente que no es GOTO. En el lado negativo, el bucle interno debe completar la iteración actual antes de terminar, por lo que podría no ser aplicable en algunos escenarios.
Me doy cuenta de que este es un tema muy antiguo, pero como mi enfoque estándar aún no está aquí, pensé que lo publicaría para los futuros googlers.
var a, b, abort = false;
for (a = 0; a < 10 && !abort; a++) {
for (b = 0; b < 10 && !abort; b++) {
if (condition) {
doSomeThing();
abort = true;
}
}
}
Pensé en mostrar un enfoque de programación funcional. Puede salir de las funciones de Array.prototype.some () y / o Array.prototype.every () anidadas, como en mis soluciones. Un beneficio adicional de este enfoque es que Object.keys()
enumera solo las propiedades enumerables de un objeto, mientras que "un bucle for-in enumera las propiedades en la cadena del prototipo también" .
Cerca de la solución del OP:
Args.forEach(function (arg) {
// This guard is not necessary,
// since writing an empty string to document would not change it.
if (!getAnchorTag(arg))
return;
document.write(getAnchorTag(arg));
});
function getAnchorTag (name) {
var res = '''';
Object.keys(Navigation.Headings).some(function (Heading) {
return Object.keys(Navigation.Headings[Heading]).some(function (Item) {
if (name == Navigation.Headings[Heading][Item].Name) {
res = ("<a href=/""
+ Navigation.Headings[Heading][Item].URL + "/">"
+ Navigation.Headings[Heading][Item].Name + "</a> : ");
return true;
}
});
});
return res;
}
Solución que reduce la iteración sobre los encabezados / elementos:
var remainingArgs = Args.slice(0);
Object.keys(Navigation.Headings).some(function (Heading) {
return Object.keys(Navigation.Headings[Heading]).some(function (Item) {
var i = remainingArgs.indexOf(Navigation.Headings[Heading][Item].Name);
if (i === -1)
return;
document.write("<a href=/""
+ Navigation.Headings[Heading][Item].URL + "/">"
+ Navigation.Headings[Heading][Item].Name + "</a> : ");
remainingArgs.splice(i, 1);
if (remainingArgs.length === 0)
return true;
}
});
});
Sé que esto se solicitó hace 8 años, pero en ES6 obtuvimos el bucle for...of que permite el uso de la funcionalidad de ruptura estándar :
for (let item of items) {
if (item.id === id) {
//do something cool
break;
}
}
Si usa Coffeescript, hay una palabra clave "do" conveniente que facilita la definición y ejecución inmediata de una función anónima:
do ->
for a in first_loop
for b in second_loop
if condition(...)
return
... así que simplemente puedes usar "return" para salir de los bucles.
bastante sencillo
var a=[1,2,3];
var b=[4,5,6];
var breakCheck1=false;
for (var i in a){
for (var j in b){
breakCheck1=true;
break;
}
if (breakCheck1) {break;}
}
la mejor manera es
1) Ordene las dos matrices que se utilizan en el primer y segundo bucle.
2) si el elemento coincide, entonces rompa el bucle interno y mantenga el valor del índice.
3) cuando comience la siguiente iteración, inicie el bucle interno con el valor del índice de retención.
XXX.Validation = function() {
var ok = false;
loop:
do {
for (...) {
while (...) {
if (...) {
break loop; // Exist the outermost do-while loop
}
if (...) {
continue; // skips current iteration in the while loop
}
}
}
if (...) {
break loop;
}
if (...) {
break loop;
}
if (...) {
break loop;
}
if (...) {
break loop;
}
ok = true;
break;
} while(true);
CleanupAndCallbackBeforeReturning(ok);
return ok;
};
var str = "";
for (var x = 0; x < 3; x++) {
(function() { // here''s an anonymous function
for (var y = 0; y < 3; y++) {
for (var z = 0; z < 3; z++) {
// you have access to ''x'' because of closures
str += "x=" + x + " y=" + y + " z=" + z + "<br />";
if (x == z && z == 2) {
return;
}
}
}
})(); // here, you execute your anonymous function
}
¿Como es que? :)