Mastering Arrays And Iteration In Go: Exploring Arrays, Loops, And Common Iteration Patterns

Overview

This chapter provides an in-depth exploration of arrays and iteration in Go. You will learn the fundamentals of arrays, including their fixed size and type, how to create and initialize them, and how Go handles array indexing. The chapter also covers common loop constructs, including for loops, range loops, and control mechanisms like continue and break. You’ll also gain hands-on experience with two-dimensional arrays, iteration patterns, and using Go’s range keyword to simplify array iteration. By the end, you’ll have a solid foundation for working with arrays and iteration in Go, setting the stage for more advanced data structures.

Arrays

Arrays are:

  • Fixed length
  • Fixed type
  • Zero based

names := [4]string{}
names[0] = "John"
names[1] = "Paul"
names[2] = "George"
names[3] = "Ringo"

Initializing An Array

Arrays can have their values set at initialization time.


package main

import "fmt"

func main() {
	names := [4]string{"John", "Paul", "George", "Ringo"}

	fmt.Println(names)
}

Array Zero Value

The zero value of each element in an array is the zero value for the type of elements in the array.

Given the following code:


names := [4]string{}
ints := [4]int{}

fmt.Printf("%q\n", names)
fmt.Println(ints)

Output:


["" "" "" ""]
[0 0 0 0]

Indexing Arrays

You will receive an error (either compile time or a panic) when trying to access an index of the array beyond it’s size.

names[4] = "Stu"
invalid array index 4 (out of bounds for 4-element array)

Array Type

It’s important to remember that an array can only be of the type is was declared. All of the following will result in compiler errors:


strings := [4]string{"one", "two", "three", "four"}
ints := [4]int{1, 2, 3, 4}

strings[0] = 5   // Can't put an int in a string array
ints[0] = "five" // Can't put a string in an int array

Output:


./main.go:7:13: cannot use 5 (type untyped int) as type string in assignment
./main.go:8:10: cannot use "five" (type untyped string) as type int in assignment

Array Type Definition

The length is actually part of the type that is defined for arrays.


package main

import "fmt"

func main() {
	a1 := [2]string{"one", "two"}
	a2 := [2]string{}

	a2 = a1

	fmt.Println(a2)
	a3 := [3]string{}

	// This can't be done, as it is not of the same type
	//a3 = a2

	fmt.Println(a3)
}

Setting Array Values

It is important to note that if you create two like arrays, and then set the value of one array to the other, they still continue to have their own memory space.


func main() {
	a1 := [2]string{"one", "two"}
	a2 := [2]string{}

	a2 = a1

	fmt.Println("a1:", a1)
	fmt.Println("a2:", a2)

	a1[0] = "bob"

	fmt.Println("a1:", a1)
	fmt.Println("a2:", a2)
}

Output:


a1: [one two]
a2: [one two]
a1: [bob two]
a2: [one two]

Two Dimensional Arrays

Go’s arrays are one-dimensional. To create an equivalent of a 2D array, it is necessary to define an array-of-arrays.


// A 3x3 array, really an array of arrays.
type Matrix [3][3]int

func main() {
	m := Matrix{
		{0, 0, 0},
		{1, 1, 1},
		{2, 2, 2},
	}

	fmt.Println(m)
}

The `for` Loop

In Go there is only one looping construct; the for loop.

Use it for for, while, do while, do until, etc…

for i := 0; i < N; i++ {
  // do work until i equals N
}

Iterating Over Arrays

Iterating over arrays is done using a for loop.


package main

import "fmt"

func main() {
	names := [4]string{"John", "Paul", "George", "Ringo"}

	for i := 0; i < len(names); i++ {
		fmt.Println(names[i])
	}
}

The len function returns the length of the array (4).

Continuing A Loop

The continue keyword allows us to go back to the start of the loop and stop executing the rest of the code in the for block.

for {
  if i == 3 {
    // go to the start of the loop
    continue
  }
  // do work
}

This does not stop the loop from executing, but rather ends that particular run of the loop.

Breaking A Loop

To stop execution of a loop we can use the break keyword.

for {
  if i == 3 {
    // stop looping
    break
  }
  // do work
}

The for loop is now stopped and will no longer run.

Do While Loop

A do while loop is used in a situation where you want the loop to run at least 1 iteration, regardless of the condition.

A C/Java-style example would look something like this:

do {
 task();
} while (condition);

To create a do while style loop in Go a combination of an infinite loop and the break keyword can be used:


var i int
for {
	fmt.Println(i)
	i += 2
	if i >= 3 {
		break
	}
}

The `range` Keyword

Previously we used a “classic” for loop to iterate over an array:


package main

import "fmt"

func main() {
	names := [4]string{"John", "Paul", "George", "Ringo"}

	for i := 0; i < len(names); i++ {
		fmt.Println(names[i])
	}
}

Looping over arrays, and other collection types, is so common that Go created the range tool to simplify this code.


package main

import "fmt"

func main() {
	names := [4]string{"John", "Paul", "George", "Ringo"}

	for i, n := range names {
		fmt.Printf("%d - %s\n", i, n)
	}
}

Range returns the index and the value of the array.

Exercise (10m)


package main

func main() {
	fruits := [4]string{"Banana", "Orange", "Pineapple", "Strawberry"}

	// Use a 'classic' for loop  to print out each fruit in the array, and the
	// corresponding index.

	// Use the range keyword to loop over the same array of fruits, again printing
	// out the fruit and the corresponding index.

	// Using the keyword `continue`, skip every other fruit (even ones)
	// HINT: the `%` is the `mod` operator in Go
}

Solution


package main

import "fmt"

func main() {
	fruits := [4]string{"Banana", "Orange", "Pineapple", "Strawberry"}

	// Use a 'classic' for loop  to print out each fruit in the array, and the
	// corresponding index.
	for i := 0; i < len(fruits); i++ {
		fmt.Println(i, fruits[i])
	}

	// Use the range keyword to loop over the same array of fruits, again printing
	// out the fruit and the corresponding index.
	for i, f := range fruits {
		fmt.Println(i, f)
	}

	// Using the keyword `continue`, skip every other fruit (even ones)
	for i, f := range fruits {
		if i%2 == 0 {
			continue
		}
		fmt.Println(i, f)
	}
}