Skip to content

C# - Nested Loops

A nested loop is a loop that is placed inside another loop. For each single iteration of the outer loop, the inner loop completes its entire sequence of iterations. This structure is very common for working with two-dimensional data, such as grids, tables, or matrices.

You can nest any type of loop inside another. The most common combination is a for loop inside another for loop.

// Nested 'for' loop syntax
for (int i = 0; i < outerMax; i++)
{
// This is the outer loop
for (int j = 0; j < innerMax; j++)
{
// This is the inner loop
// Code here executes innerMax times for EACH outer loop iteration
}
}

A key point is that the total number of inner loop executions is the product of the outer and inner loop counts (e.g., if the outer loop runs 3 times and the inner loop runs 4 times, the innermost code block will execute 3 * 4 = 12 times).

Practical Example: Generating a Multiplication Table

Section titled “Practical Example: Generating a Multiplication Table”

A multiplication table is a classic and intuitive example of a nested loop. The outer loop iterates through the rows (multiplicand), and the inner loop iterates through the columns (multiplier).

using System;
int tableSize = 5;
// Outer loop for rows (1 to 5)
for (int i = 1; i <= tableSize; i++)
{
// Inner loop for columns (1 to 5)
for (int j = 1; j <= tableSize; j++)
{
// {i * j, -4} pads the number to 4 characters for alignment
Console.Write($"{i * j, -4}");
}
// Move to the next line after each row is complete
Console.WriteLine();
}

The code produces a neatly formatted multiplication table:

1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25

Nested loops are essential for processing two-dimensional arrays. The outer loop typically iterates over the rows, and the inner loop iterates over the columns within each row.

using System;
// A 2D array representing a simple game board
char[,] board =
{
{ 'X', 'O', 'X' },
{ 'O', 'X', 'O' },
{ 'O', 'O', 'X' }
};
// Get the number of rows and columns
int rows = board.GetLength(0);
int cols = board.GetLength(1);
Console.WriteLine("Game Board:");
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
Console.Write($"{board[i, j]} ");
}
Console.WriteLine();
}
Game Board:
X O X
O X O
O O X

We can use nested loops to find prime numbers within a range. A number is prime if it is only divisible by 1 and itself. The outer loop iterates through numbers to check, and the inner loop checks for factors.

using System;
Console.WriteLine("Prime numbers between 2 and 100:");
// Outer loop: Iterate through each number to test
for (int numberToTest = 2; numberToTest <= 100; numberToTest++)
{
bool isPrime = true;
// Inner loop: Check for factors from 2 up to the square root of the number.
// This is an optimization: if a number has a factor larger than its square root,
// it must also have a smaller one.
for (int factor = 2; factor * factor <= numberToTest; factor++)
{
if (numberToTest % factor == 0)
{
isPrime = false;
break; // Factor found, not a prime. Exit the inner loop.
}
}
if (isPrime)
{
Console.Write($"{numberToTest} ");
}
}
Console.WriteLine();

The above code generates a list of prime numbers:

Prime numbers between 2 and 100:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

Performance Considerations and Best Practices

Section titled “Performance Considerations and Best Practices”
  • Be Mindful of Complexity: Nested loops can lead to poor performance if the collections are large. A nested loop over n items typically has a time complexity of O(n²) (O-n-squared). This means if you double the input size, the execution time roughly quadruples.
  • Avoid Deep Nesting: Code with three or more levels of nested loops can become very difficult to read and debug. If you find yourself needing deep nesting, consider refactoring your code into smaller, more specialized methods.
  • Use break to Optimize: As seen in the prime number example, use break to exit an inner loop as soon as you have the result you need. This can prevent many unnecessary iterations.
  • Consider Alternatives: For some complex data-processing tasks, using LINQ (Language-Integrated Query) can provide a more readable and declarative alternative to manual nested loops.