Skip to content

Chapter 12: Iterating Data - The 'foreach' Loop and Array Traversal

Theoretical Foundations

In the previous chapter, we learned about arrays (Chapter 11). An array is a fixed-size container for variables of the same type. We access these variables using an index, which is just a number representing the position of an item in the list (starting at 0).

For example, if we have an array of integers, we access them like this:

int[] scores = { 100, 95, 80 };
// We access them individually:
Console.WriteLine(scores[0]); // Prints 100
Console.WriteLine(scores[1]); // Prints 95
Console.WriteLine(scores[2]); // Prints 80

While this works, it requires us to manually track the size of the array and manage the index numbers. If we want to process every item in the array, we usually use a for loop (Chapter 9). However, C# provides a specialized loop designed specifically for this task: the foreach loop.

The "Shopping List" Analogy

Imagine you have a physical shopping list on a piece of paper.

  1. The for loop approach: To read this list, you might say to yourself: "Look at line 1, read it. Look at line 2, read it. Look at line 3, read it." You are explicitly managing the line numbers (the index).
  2. The foreach loop approach: You simply pick up the paper and scan your eyes down it. You don't think "line 1, line 2." You just read what is there. You are saying, "For every item in this list, do something."

The foreach loop lets you focus on the data (the items) rather than the mechanics (the indexes).

Syntax and Structure

The foreach loop is designed to be readable. It reads almost like an English sentence.

Allowed Syntax:

foreach (type variableName in collectionName)
{
    // Code to execute for each item
}

Breakdown:

  • foreach: The keyword that starts the loop.
  • ( ... ): Contains the declaration of how to handle the items.
  • type variableName: This declares a new variable that will hold the current item being looked at during that specific cycle of the loop. The type must match the type of items in the array (or be a type it can be converted to).
  • in: A keyword separating the temporary variable from the source of data.
  • collectionName: The array we want to iterate over.

Example:

using System;

class Program
{
    static void Main()
    {
        // 1. We define an array of strings (Chapter 11)
        string[] pets = { "Dog", "Cat", "Parrot" };

        // 2. The foreach loop
        foreach (string pet in pets)
        {
            // 'pet' is a temporary variable. 
            // In the first loop, it is "Dog".
            // In the second loop, it is "Cat".
            // In the third loop, it is "Parrot".
            Console.WriteLine("I have a " + pet);
        }
    }
}

Output:

I have a Dog
I have a Cat
I have a Parrot

How It Works Internally (The "Black Box")

You do not need to write the code for the foreach loop to work, but understanding the logic helps.

When the compiler sees foreach (string pet in pets), it essentially does the following automatically:

  1. It looks at the array pets.
  2. It grabs the item at index 0 and puts it into the variable pet.
  3. It runs the code inside the { }.
  4. It grabs the item at index 1 and puts it into pet.
  5. It runs the code inside the { }.
  6. It repeats this until it reaches the end of the array.

Comparison: for vs. foreach

Why learn foreach if we already know for loops (Chapter 9)?

1. The for loop (Manual Control): You have access to the index number (i).

int[] numbers = { 10, 20, 30 };
for (int i = 0; i < numbers.Length; i++)
{
    // We can access the index
    Console.WriteLine("Item at index " + i + " is " + numbers[i]);

    // We can modify the array
    numbers[i] = numbers[i] + 1; 
}

2. The foreach loop (Read-Only & Simple): You do not have access to the index number. You only have the value.

int[] numbers = { 10, 20, 30 };
foreach (int num in numbers)
{
    // We CANNOT easily know what index 'num' is at.
    // We CANNOT modify the array 'numbers' directly using 'num'.

    Console.WriteLine("The value is " + num);
}

Key Rule: The foreach loop is primarily for reading data. It is safer because it prevents you from accidentally accessing an index that doesn't exist (like index 10 in an array of size 3).

Iterating Over Different Types

The foreach loop works on any array type, as long as you declare the correct variable type inside the loop.

Integers:

int[] scores = { 90, 85, 92 };
foreach (int score in scores)
{
    Console.WriteLine(score);
}

Doubles:

double[] prices = { 1.99, 2.50, 3.00 };
foreach (double price in prices)
{
    Console.WriteLine(price);
}

Booleans:

bool[] flags = { true, false, true };
foreach (bool flag in flags)
{
    if (flag == true)
    {
        Console.WriteLine("Flag is active");
    }
}

Nested foreach Loops (Multi-Dimensional Arrays)

In Chapter 11, we touched on multi-dimensional arrays (grids). We can use foreach loops inside other foreach loops to "dig" into the data.

Imagine a grid of integers (like a chessboard).

using System;

class Program
{
    static void Main()
    {
        // A 2x3 grid (2 rows, 3 columns)
        int[,] grid = {
            { 1, 2, 3 },
            { 4, 5, 6 }
        };

        // Outer loop: Iterates over the rows
        // In a 2D array, the first item is the 'row' dimension.
        // However, 'foreach' doesn't care about dimensions, it just grabs chunks.

        // To be strict with allowed concepts, we treat the 2D array as a sequence of rows.
        // But to visualize it, we usually use nested loops.

        // Let's look at the rows first.
        // We need to know how many rows exist. We use the .GetLength(0) method (allowed in Ch 11).
        int rows = grid.GetLength(0);
        int cols = grid.GetLength(1);

        // We will use a standard 'for' loop for the rows because 'foreach' on a 2D array
        // returns 1D arrays (which might be confusing for a beginner right now).
        // But let's stick to the pure 'foreach' concept where possible.

        // Actually, strictly speaking, 'foreach' on a multi-dimensional array iterates linearly.
        // But to make it understandable, let's simulate the grid traversal logic using allowed concepts.

        Console.WriteLine("--- Reading the Grid ---");

        // We know the size of the first dimension (rows)
        for (int i = 0; i < grid.GetLength(0); i++)
        {
            // We know the size of the second dimension (cols)
            for (int j = 0; j < grid.GetLength(1); j++)
            {
                // Accessing specific index
                int value = grid[i, j];
                Console.Write(value + " ");
            }
            Console.WriteLine(); // New line after every row
        }
    }
}
Note: While we used for loops here for the indices, a foreach loop on grid would simply give us {1, 2, 3} then {4, 5, 6} (which are the rows themselves as arrays). For beginners, the nested for loop is often clearer for grids, but foreach is excellent for simple lists.

The "Read-Only" Safety Feature

One of the most important rules of foreach is that it protects the collection.

Inside a foreach loop, the variable (e.g., pet or score) is read-only. You cannot change the value inside the array using that variable.

int[] numbers = { 1, 2, 3 };

foreach (int num in numbers)
{
    // This is ILLEGAL. It will cause a compiler error.
    // num = num + 1; 

    // Why? Because 'num' is a copy of the value in the array, 
    // or a protected reference. Changing 'num' doesn't change 'numbers'.

    // However, if the array held objects (later chapters), 
    // you could modify properties, but for simple types like int, it is forbidden.
}

When to use foreach vs. for

  1. Use foreach when:

    • You want to look at every item in a collection.
    • You don't need to know the index number (position).
    • You don't need to modify the items in the collection.
    • You want cleaner, easier-to-read code.
  2. Use for when:

    • You need to know the position (e.g., "Print the 5th item").
    • You need to modify the array items (e.g., numbers[i] = 0).
    • You need to iterate backwards or skip items in a complex pattern.

The foreach loop is a specialized tool for iterating over a collection of data. It abstracts away the complexity of managing index numbers (i++, i < length), allowing you to focus purely on the data itself. It relies on the array having a defined order and size (fixed in Chapter 11), and it ensures safety by preventing modification of the collection structure during iteration.

In AI development, you will often receive data in arrays (e.g., a batch of text inputs, a set of sensor readings). Using foreach allows you to process these inputs one by one cleanly without worrying about the underlying count.

A foreach loop processes a batch of inputs—such as text or sensor readings—sequentially and cleanly, handling each item individually without needing to know the total count.
Hold "Ctrl" to enable pan & zoom

A `foreach` loop processes a batch of inputs—such as text or sensor readings—sequentially and cleanly, handling each item individually without needing to know the total count.

Basic Code Example

Here is a simple, "Hello World" level code example demonstrating the foreach loop for iterating over an array.

using System;

// REAL-WORLD CONTEXT:
// Imagine you are organizing a digital playlist. You have a fixed list of song titles
// stored in an array. You want to display each song title to the user one by one.
// Using a 'foreach' loop is the cleanest way to read through every item in the list.

class Program
{
    static void Main()
    {
        // 1. We declare an array of strings to hold our playlist.
        //    Arrays are fixed-size collections (Chapter 11).
        string[] playlist = { "Bohemian Rhapsody", "Stairway to Heaven", "Hotel California" };

        // 2. We use the 'foreach' loop to iterate over the array.
        //    This loop automatically visits every element from start to finish.
        //    'song' is a temporary variable that holds the current element.
        foreach (string song in playlist)
        {
            // 3. Inside the loop body, we print the current song to the console.
            Console.WriteLine($"Now playing: {song}");
        }
    }
}

How the Code Works: Step-by-Step

  1. Array Initialization: We create a string array named playlist. It contains three specific song titles. The array knows its size (3) immediately upon creation.

  2. The foreach Statement: The line foreach (string song in playlist) acts as a command: "For every item inside playlist, assign that item to the variable song, and execute the code block below."

    • string song: This defines the type and name of the variable that will hold the current item. Since playlist holds strings, song must be a string.
    • in playlist: This specifies the collection we want to read.
  3. Execution Flow:

    • Iteration 1: The loop picks the first item ("Bohemian Rhapsody"). song becomes "Bohemian Rhapsody". The Console.WriteLine executes.
    • Iteration 2: The loop picks the second item ("Stairway to Heaven"). song becomes "Stairway to Heaven". The Console.WriteLine executes.
    • Iteration 3: The loop picks the third item ("Hotel California"). song becomes "Hotel California". The Console.WriteLine executes.
  4. Termination: Once the loop processes the last item in the array, it automatically stops. You do not need to manage an index counter or check boundaries manually.

Visualizing the Loop Execution

The following diagram illustrates how the foreach loop moves through the array indices sequentially.

Diagram: G
Hold "Ctrl" to enable pan & zoom

Common Pitfalls

Attempting to Modify the Array Inside the Loop A common mistake beginners make is trying to change the value of the array element using the iteration variable.

// ❌ INCORRECT CODE - This will not compile
foreach (string song in playlist)
{
    // Error: Cannot assign to 'song' because it is a 'foreach iteration variable'
    song = "New Song"; 
}

Why this happens: The variable song is a read-only copy of the current element. It exists only for the duration of that specific iteration to let you read the value. You cannot use foreach to modify the contents of the array directly. If you need to modify array elements, you must use a standard for loop (Chapter 9) using an index (e.g., playlist[i] = "New Song";).

The chapter continues with advanced code, exercises and solutions with analysis, you can find them on the ebook on Leanpub.com or Amazon



Code License: All code examples are released under the MIT License. Github repo.

Content Copyright: Copyright © 2026 Edgar Milvus | Privacy & Cookie Policy. All rights reserved.

All textual explanations, original diagrams, and illustrations are the intellectual property of the author. To support the maintenance of this site via AdSense, please read this content exclusively online. Copying, redistribution, or reproduction is strictly prohibited.