Range Over Built-in Types

3-minute read
Table of Contents

The range keyword in Golang allows us to iterate over the elements in numerous built-in types. We can range over numbers, slices, etc., with a simple syntax.

Range over slice

We can range over the individual elements in a slice without using the index of each element - here we use the blank identifier _ where the index would be:

package main

import "fmt"

func main() {
	sum := 0
	nums := []int{1, 2, 3, 4, 5, 6}

	for _, num := range nums {
		sum += num
	}

	fmt.Println("sum:", sum)
}
range-over-slice.go
Copy

Slice with index

We can also make use of the index if we so desire:

package main

import "fmt"

func main() {
	nums := []int{1, 2, 3, 4, 5, 6}

	for i, num := range nums {
		if num%2 == 0 {
			fmt.Println("even number at index:", i, "value:", num)
		}
	}
}
range-over-slice-with-index.go
Copy

Range over map

We can access both the keys and values of maps using range. Try running the following program multiple times:

package main

import "fmt"

func main() {
	myMap := map[string]string{
		"a": "apple",
		"b": "banana",
		"o": "orange",
	}
	for key, value := range myMap {
		fmt.Println("key: ", key, ", value:", value)
	}
}
range-over-map.go
Copy

Notice how we do not get the same output each time we run this program. This is because maps are unordered in Golang thus are not guaranteed to produce the same results via iteration.

Slices, unlike maps, are ordered and will produce the same results each time we iterate through them.

Map keys only

We can also access only the keys if we so desire:

package main

import "fmt"

func main() {
	myMap := map[string]string{
		"a": "apple",
		"b": "banana",
		"o": "orange",
	}
	for key := range myMap {
		fmt.Println("key: ", key)
	}
}
range-over-map-keys.go
Copy

Range over string

In the same way that we can loop through a slice or array, we can loop through a string, treating the string as a read-only slice of bytes listed as runes (integers that represent Unicode code points). We can get the index of each rune and the value of each using range:

package main

import "fmt"

func main() {
	sentence := "Hello Tèè!"
	for i, c := range sentence {
		fmt.Println("index:", i, ", rune:", c)
	}
}
range-over-string.go
Copy

The output value for each rune is an integer that represents the current character in the string.

Some characters such as those with special letter formations such as è may require multiple runes to represent them.

We can see each rune by using range with the length of the string:

package main

import (
	"fmt"
)

func main() {
	sentence := "Hello Tèè!"
	for i := range len(sentence) {
		fmt.Println("index:", i, "rune:", sentence[i], ", unicode string:", string(sentence[i]))
	}
}
range-over-string-bytes.go
Copy

Support us via BuyMeACoffee