programacion-anidacion-bucles

Anidación de bucles

La anidación de bucles es una estructura de control que consiste en meter bucles dentro de otros bucles.

Aquí bucle puede ser cualquiera de los que hemos visto WHILE, DOWHILE, FOR, FOREACH, según lo que tenga disponible nuestro lenguaje.

La anidación de bucles es especialmente útil (y necesaria) cuando se requiere iterar sobre estructuras de datos complejas o cuando se necesita realizar operaciones repetitivas en diferentes niveles de jerarquía.

Al meter un bucle dentro de otro bucle, tendremos una estructura como la siguiente:

programacion-loop-nested

Esquema bucles anidados
  • El bucle externo, será el bucle que encierra a otros bucles.
  • Dentro de este, definimos el bucle interno.

Que traspasado a código, tendría la siguiente pinta:

bucle(...) // bucle externo 🔵
{
	// Acciones que antes del bucle interno
	  
    bucle(...)  // bucle interno 🟨
    {
        // Acción que se repite en bucle interno
    }
    
    // Acción que después de bucle externo
}

Al ejecutarse el código:

  • Primero se ejecuta el bucle externo 🔵.
  • Se ejecutan las líneas antes del bucle interno 🔵.
    • Al llegar al bucle interno 🟨, el código se queda “ahí atrapado dando vueltas” 🔁.
  • Al finalizar el bucle interno, se ejecutan las líneas restantes del bucle externo 🔵.
  • Al llevar al final del bucle externo, este se repite 🔁.

Ejemplos de anidación de condicionales

Vamos a ver un ejemplo en diferentes lenguajes de programación de cómo realizar una anidación de bucles:

for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 3; j++)
    {
        // Acción que se repite en bucle interno
    }
    // Acción que se repite en bucle externo
}
for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 3; j++)
    {
        // Acción que se repite en bucle interno
    }
    // Acción que se repite en bucle externo
}
for (let i = 0; i < 5; i++)
{
    for (let j = 0; j < 3; j++)
    {
        // Acción que se repite en bucle interno
    }
    // Acción que se repite en bucle externo
}
for i in range(5):
    for j in range(3):
        # Acción que se repite en bucle interno
    # Acción que se repite en bucle externo

En estos ejemplos, hemos realizado un bucle de tipo FOR, con:

  • 5 repeticiones del bucle externo
  • 3 repeticiones del bucle interno

Esto significa que, en total:

  • El bucle externo se repite 5 veces
  • El bucle interno se repite 5 x 3 = 15 veces.

Buenas prácticas Consejos

La anidación de bucles es frecuente, y necesaria para resolver problemas complejos (especialmente en estructuradas y agrupaciones).

Por ejemplo, imagina el siguiente código, que simula evaluar todos los alumnos de una clase.

foreach(aula)
{
   foreach(alumno in aula)
   {
      evaluar_alumno(alumno)
   }
}

Si tengo que realizar ese calculo para todas las aula y todos los alumnos de cada una de ellas, un bucle anidado es la solución más sencilla.

Sin embargo, la anidación de bucles también tiene sus problemas. La principal de ellas es que la cantidad de bucles que se ejecutamos aumenta exponencialmente.

Si, por ejemplo, tienes un bucle que se ejecuta 10.000 veces, dentro de un bucle que se ejecuta 10.000 veces, ¡el bucle interno se va a ejecutar 100 millones de veces!

for(10000)
{	  
    for(10000)
    {
        // esto se va a ejecutar 100.000.000 de veces!!
    }
}

Ahora imagina si dentro metes otro bucle más… ⌛⌛⌛ … Es decir, tampoco te vengas arriba metiendo bucles dentro de bucles.

Otro problema es que en bucles de tipo WHILE, puede complejizar la condición de salida. Es más fácil que te metas en un bucle infinito.

La última es que puede ser un código más complejo de entender. Por ejemplo, el ejemplo anterior podría ser más sencillo de entender si “partirmos” la función evaluar_alumno y evaluar_aula.

foreach(aula)
{
   evaluar_aula(aula)
}

function evaluar_aula(aula)
{
   foreach(alumno in aula)
   {
      evaluar_alumno(alumno)
   }
}

Como siempre, es importante que mantengas una estructura de código clara y legible, de forma que sea fácil de entender para ti o para el siguiente que la lea.