Start learning free

LESSON 145 OF 338 · LOOPING OVER ARRAY INDICES

Looping Through a Slice with Indices in Go

Lesson Read the full explanation

In some instances, we will want to loop through an array using indices.

The indices of an array meals are all the integer values from 0 to len(meals) - 1, so we can iterate over them using an index variable i:

meals := []string{"pancakes", "pasta", "pizza", "avocado"}

for i := 0; i < len(meals); i++ {
	fmt.Printf("Meal number %d is %s.\n", i+1, meals[i])
}

The output of this code is:

Meal number 1 is pancakes.
Meal number 2 is pasta.
Meal number 3 is pizza.
Meal number 4 is avocado.

Assignment
Now let's print the temperature on each day, in this format:

On day 1 the temperature is 10.

On day 2 the temperature is 60.

...


Hint
Look at the examples above if you get stuck.


STEP 1 OF 2
    Ctrl + Enter to check

    GO · LOOPING OVER ARRAY INDICES

    Looping Through Arrays With Indices in Go, explained

    Why loop with indices

    Go gives you two ways to walk through a slice. A for ... range loop hands you each element. A counting loop hands you each index, and you read the element yourself with nums[i]. The index form is the one to reach for when the position matters: when you need to print it, return it, change the element in place, or look at a neighbour such as nums[i+1].

    The valid indices of a slice meals are the integers from 0 to len(meals) - 1. The built-in len returns the number of elements, and indexing starts at 0, so the last element sits at len(meals) - 1.

    The three-part for loop

    Go has only one loop keyword, for, and its classic form has three parts separated by semicolons: a starting statement, a condition checked before every pass, and a statement that runs after every pass.

    meals := []string{"pancakes", "pasta", "pizza", "avocado"}
    
    for i := 0; i < len(meals); i++ {
        fmt.Printf("Meal number %d is %s.\n", i+1, meals[i])
    }
    

    This prints:

    Meal number 1 is pancakes.
    Meal number 2 is pasta.
    Meal number 3 is pizza.
    Meal number 4 is avocado.
    

    Reading the header piece by piece:

    • i := 0 declares the index, which exists only inside the loop, and starts it at the first position.
    • i < len(meals) keeps the loop going while i is a valid index. The condition uses < and not <=, because len(meals) itself is one past the last element.
    • i++ moves to the next position after each pass.

    There are no parentheses around the header and the braces are required. Go also has no while keyword: this form, or a for with only a condition, covers every case.

    Counting from 1 for display

    People count meals from 1, while indices start at 0. The example prints i+1 for the meal number and meals[i] for the element. Keep the two roles separate: i is the position in the slice, and i+1 is only a label.

    Other directions and ranges

    The three parts can be changed to fit the task. This loop walks backwards, from the last index to 0:

    nums := []int{4, 8, 15}
    for i := len(nums) - 1; i >= 0; i-- {
        fmt.Println(i, nums[i])
    }
    

    It prints 2 15, then 1 8, then 0 4. To compare each element with the next one, stop one index early so that i+1 stays valid:

    for i := 0; i < len(nums)-1; i++ {
        fmt.Println(nums[i], "then", nums[i+1])
    }
    

    This prints 4 then 8 and 8 then 15.

    Common mistakes

    • Using <= with len. The loop for i := 0; i <= len(nums); i++ reaches i == 3 for a three-element slice. Go checks indices at run time, so the program prints the three elements and then stops with panic: runtime error: index out of range [3] with length 3.
    • Printing a number with +. Go does not join an int to a string with +: "day " + i does not compile. Convert the number first with strconv.Itoa(i), or use fmt.Printf with %d.
    • Forgetting that the day is i+1. Printing i directly starts the numbering at 0.

    The exercise

    The slice temperatures holds 10, 60, -5, 32. The task is to print one line per day in the form On day 1 the temperature is 10., with the day counted from 1.

    1. Write the loop. Declare the index i with :=, start it at 0, continue while it is less than len(temperatures), and increment it after each pass.
    2. Build the text. The line has a day number and a temperature, both integers. Each is converted with strconv.Itoa and joined to the surrounding text with +. The day is i+1 and the temperature is temperatures[i].
    3. Print it with fmt.Println.
    temperatures := []int{10, 60, -5, 32}
    
    for i := 0; i < len(temperatures); i++ {
        fmt.Println("On day " + strconv.Itoa(i+1) + " the temperature is " + strconv.Itoa(temperatures[i]) + ".")
    }
    

    The output is:

    On day 1 the temperature is 10.
    On day 2 the temperature is 60.
    On day 3 the temperature is -5.
    On day 4 the temperature is 32.
    

    The code uses the fmt and strconv packages, so both are imported in a full program. The negative temperature needs no special care: strconv.Itoa(-5) gives "-5".

    Key takeaways

    • The valid indices of a slice run from 0 to len(s) - 1.
    • The loop for i := 0; i < len(s); i++ visits each index once. Use <, not <=.
    • Use index loops when you need positions, neighbours or in-place changes. Use range when only the values matter.
    • Go does not add an int to a string with +: convert it with strconv.Itoa or format it with fmt.Printf.
    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free