c objective-c loops

¿Cómo puedo salir de dos bucles anidados para Objective-C?



loops (13)

Además de la variable de bandera ya mencionada o goto, podría throw una excepción Objective-C:

@try { for() { for() { @throw ... } } } @catch{ ... }

Tengo dos bucles for anidados como este:

for(...) { for(...) { } }

Sé que hay una declaración de break . Pero estoy confundido acerca de si rompe ambos bucles o solo aquel en el que se llamó? Necesito romper ambos una vez que veo que no tiene sentido iterar más veces.


Cambiar el contador del bucle superior antes del descanso

for(i=0; i<10 ; i++) for(j=0;j< 10; j++){ .. .. i = 10; break; }


Exactamente como los últimos son, generalmente así:

for(i=0;i<a;i++){ for(j=0;j<a;j++){ if(Something_goes_wrong){ i=a; break; } } }


La declaración de break solo te saca del ciclo más interno. Si no desea la sobrecarga adicional en el código, la memoria y el rendimiento de una variable de estado dedicada, recomiendo refactorizar el código en una función o método propio, y usar return para salir de todos los loops:

void do_lots_of_work(void) { int i, j; for(i=0; i<10 ; i++) { for(j=0;j< 10; j++) { .. .. if(disaster_struck()) return; /* Gets us out of the loops, and the function too. */ } } }


La declaración de ruptura se rompe fuera del ciclo más interno. Se necesitaría una declaración adicional de prueba y pausa para salir del bucle externo.


La instrucción break solo saldrá del bucle en el alcance, que es el bucle padre. Si también quieres salir del segundo ciclo, podrías usar una variable booleana que está en el alcance de ambos bucles

bool isTerminated = false; for (...) { if (!isTerminated) { for(...) { ... isTerminated = true; break; } } else { break; } }


Otra solución es factorizar el segundo ciclo en una función:

int i; for(i=0; i<10 ; i++){ if !innerLoop(i) { break; } } bool innerLoop(int i) int j; for(j=0;j< 10; j++){ doSomthing(i,j); if(endcondtion){ return false; } } }


Otros han mencionado cómo puede establecer una bandera o usar un goto , pero recomiendo refactorizar su código para que el bucle interno se convierta en un método separado. Ese método puede devolver una bandera para indicar que el bucle externo debería break . Si nombra sus métodos de manera apropiada, esto es mucho más legible.

for (int i = 0; i < 10; i++) { if (timeToStop(i)) break; } -(bool) timeToStop: (int) i { for (int j = 0; j < 10; j++) { if (somethingBadHappens) return true; } return false; }

Pseudocódigo, no probado, pero entiendes la idea.


Probablemente la forma más fácil es usar una variable "flag"

for(i=0; i<10 && (done==false); i++) for(j=0;j< 10; j++){ .. .. if(...){done=true; break;} }


Si se ejecuta un corte desde dentro de un conjunto de bucles anidados, solo se termina el bucle más interno en el que se ejecuta el corte. (Al igual que el estándar C)


Si usar goto simplifica el código, entonces sería apropiado.

for (;;) { for (;;) { break; /* breaks inner loop */ } for (;;) { goto outer; /* breaks outer loop */ } } outer:;


Solo por sonrisas, ¿qué hay de cambiar este cheque verdadero / falso en un método y usar declaraciones de return ?

- (bool) checkTrueFalse: parameters{ for ( ...) { for ( ... ) { if (...) { return true; } } } return false; }


ruptura se rompe de un bucle, pero puede agregar una verificación al bucle externo que se rompe cuando el interior se rompe.

bool dobreak = false; for ( ..; !dobreak && ..; .. ) { for ( ... ) { if (...) { dobreak = true; break; } } }