Concepts / Introduction to For-each Loops for Array Processing

Introduction to For-each Loops for Array Processing

A for-each loop processes the values in an array, not the elements themselves, so assigning to the loop variable does not change the array.

  • Programming

A Tempting Assumption About Loop Variables

A for-each loop seems to hand you each position of an array, one after another. Because of that, it is natural to expect that writing to the loop variable will write into the array. Many learners expect that a line such as item = 17 inside the loop will fill the array with 17s. This lesson tests that belief against what the loop actually does, and it shows where the for-each loop is a good fit and where it is not.

What do you think happens?

Inside a for-each loop over an array, the body runs item = 17. What happens to the array?

  • Every element of the array becomes 17

  • Only the element at the current position becomes 17

  • The array keeps its original values, and only item changes

Reveal answer
Answer:

The array keeps its original values, and only item changes.

The for-each loop supplies values to the loop variable. The assignment item = 17 gives the name item the value 17, but it never names the array slot that supplied the value, so the array is not reached.

Tracing the Loop Variable Pass by Pass

Consider a small array of three values, 4, 9, and 12. The source describes the array as having its own slots, with the loop variable as a separate name. Follow what happens on the first pass. The loop reads the value 4 from the first slot and gives it to the loop variable item. The body then assigns 17 to item. At this point item refers to 17, but the first slot of the array still holds 4.

java
Notes on the code
  • intList is the array, with three slots holding the values 4, 9, and 12
  • The for-each header gives item one value per pass, starting with 4
  • item = 17 rebinds the loop variable only; no array slot is named in this statement
  • On the next pass item receives 9 from the array, replacing the earlier assignment

On the second pass the loop takes the value 9 from the second slot and gives it to item. The earlier assignment of 17 is simply replaced. The same thing happens on the third pass with 12. When the loop ends, the array still holds 4, 9, and 12. Nothing in the array was changed, because the loop never gave the array a chance to be written to.

intList[0]4item17intList[1]9intList[2]12value 4 read on first pass
When the loop variable is assigned a new value, does the cell in the array change, or does only the loop variable's own storage change?

The diagram shows the situation after the body has run on the first pass. The three array cells stand in for the full array, and the same reasoning applies to every slot. Only the loop variable has been reassigned. The array cells keep the values they had before the loop started.

Values Versus the Elements That Hold Them

Definition

A value is the piece of data stored in a slot. An element is the actual memory location that is part of the array and that holds the value. The array is the collection of these elements, and each element carries one value at a time.

The two words sound alike in everyday speech, but they point to different things. The element is the slot, the place that stays part of the array. The value is what sits inside that slot right now. A for-each loop is built around values. On each pass it supplies the next value from the array to the loop variable. It does not hand you the element itself. That is why changing the loop variable has no effect on the array: you have received a value, and a value on its own does not point back to the slot it came from.

A useful way to read the loop variable is as a name that is given a value for one pass through the body. When the body executes item = 17, the name item is associated with 17. The array element that supplied the value was never named in that statement, so nothing in the array is reached. The next pass gives item the next value from the array, and the earlier assignment is replaced.

Where a For-each Loop Falls Short

The for-each loop is not always the right tool. The source states that there is no simple way to use it to process only part of an array, and that it cannot walk the elements in reverse order. Its strength is the opposite case: when you want to process all the values in order, it makes the code a little simpler, because it removes the need for array indices.

TaskFor-each loopIndexed loop
Read every value in orderWell suited; the loop is simplerWorks, but needs an index
Process only part of the arrayNot suitableSuitable; the index can start or stop anywhere
Walk the array in reverse orderNot suitableSuitable; the index can count down
Change array elementsDoes not change the arraySuitable; assign to arr[i]

Choosing between a for-each loop and an indexed loop

Watching an Indexed Loop Write to the Array

When the goal is to change the array, the loop has to name the slot being changed. An indexed loop does this by using the index to refer to the element directly. The source gives the form intList[i] = ..., which assigns to the specific slot at position i. The example below is an illustration written for this lesson, not an excerpt from the source. It shows the same three-slot array being filled, this time done correctly.

java
Notes on the code
  • The index i names each slot by its position
  • intList[i] = 17 assigns to the slot itself, not to a temporary name
  • The loop counts from 0 up to the last position
Before
int[] intList = {4, 9, 12};
for (int item : intList) {
    item = 17;
}

intList still holds 4, 9, 12; only the loop variable item was assigned

After
int[] intList = {4, 9, 12};
for (int i = 0; i < intList.length; i++) {
    intList[i] = 17;
}

intList holds 17, 17, 17; each slot was assigned through its index

intList[0]4item4intList[0]4item17intList[1]9intList[1]9intList[2]12intList[2]12
What does the array look like before and after the loop body assigns to the loop variable, and why is it unchanged?
Pass 1: i = 0intList[0] becomes 17Pass 2: i = 1intList[1] becomes 17Pass 3: i = 2intList[2] becomes 17Loop endsall slots writteni++i++i reaches length
How does an indexed loop reach each slot by position so that writing to arr[i] changes the array?

Mistakes Beginners Make with For-each Loops

  • Common mistake

    Expecting the loop variable to write back into the array

    What it looks like
    for (int item : intList) { item = 17; }
    Why it fails

    The loop supplies a value to item. The assignment changes the name item, not the slot that supplied the value.

    Do this instead

    Use an indexed loop and assign to intList[i] when the array must change.

  • Common mistake

    Using a for-each loop to process only part of an array

    Why it fails

    A for-each loop visits the values in order from start to finish; the source notes there is no simple way to restrict it to part of an array.

    Do this instead

    Switch to an indexed loop whose index starts and stops at the positions you need.

  • Common mistake

    Trying to walk a for-each loop backward

    Why it fails

    The for-each loop cannot walk the elements in reverse order.

    Do this instead

    Use an indexed loop that counts down from the last position to 0.

  • Common mistake

    Treating value and element as the same thing, so that a changed value seems to imply a changed slot

Choosing the Right Loop

MEDIUM

An array holds the values 4, 9, and 12. You want to add 1 to every value in the array. Would you use a for-each loop or an indexed loop, and why? Write the loop you would use.

Hints
  • Ask whether the goal is to read values or to change the slots that hold them
  • Remember that the loop variable receives a value, not a slot
  • An indexed loop can assign to intList[i] directly

Carrying the Value Idea Forward

  1. 1
    A for-each loop processes the values in an array, not the elements themselves
  2. 2
    Assigning to the loop variable changes only that name, so the array is unchanged
  3. 3
    To modify elements, use an indexed loop and assign to the specific slot, such as intList[i]
  4. 4
    For-each suits reading every value in order; it is not suitable for partial traversal or reverse order

Key Takeaways

  • A for-each loop supplies values from the array to the loop variable, so assigning to the loop variable does not change the array
  • An element is the memory location that is part of the array and holds a value; the loop variable receives the value, not the element
  • A for-each loop is well suited to reading every value in order but is not suitable for partial traversal or reverse order
  • To change array elements, use an indexed loop and assign to the specific slot, such as intList[i]