Is there a foreach loop in Go?

GoForeachSlice

Go Problem Overview


Is there a foreach construct in the Go language? Can I iterate over a slice or array using a for?

Go Solutions


Solution 1 - Go

https://golang.org/ref/spec#For_range

> A "for" statement with a "range" clause iterates through all entries > of an array, slice, string or map, or values received on a channel. > For each entry it assigns iteration values to corresponding iteration > variables and then executes the block.

As an example:

for index, element := range someSlice {
	// index is the index where we are
	// element is the element from someSlice for where we are
}

If you don't care about the index, you can use _:

for _, element := range someSlice {
	// element is the element from someSlice for where we are
}

The underscore, _, is the blank identifier, an anonymous placeholder.

Solution 2 - Go

Go has a foreach-like syntax. It supports arrays/slices, maps and channels.

Iterate over an array or a slice:

// index and value
for i, v := range slice {}

// index only
for i := range slice {}

// value only
for _, v := range slice {}

Iterate over a map:

// key and value
for key, value := range theMap {}

// key only
for key := range theMap {}

// value only
for _, value := range theMap {}

Iterate over a channel:

for v := range theChan {}

Iterating over a channel is equivalent to receiving from a channel until it is closed:

for {
    v, ok := <-theChan
    if !ok {
        break
    }
}

Solution 3 - Go

Following is the example code for how to use foreach in golang

package main

import (
	"fmt"
)

func main() {
	
	arrayOne := [3]string{"Apple", "Mango", "Banana"}
	
	for index,element := range arrayOne{
	
		fmt.Println(index)
		fmt.Println(element)		
	
	}	
	
}

This is a running example https://play.golang.org/p/LXptmH4X_0

Solution 4 - Go

The following example shows how to use the range operator in a for loop to implement a foreach loop.

func PrintXml (out io.Writer, value interface{}) error {
    var data []byte
    var err error

    for _, action := range []func() {
        func () { data, err = xml.MarshalIndent(value, "", "  ") },
        func () { _, err = out.Write([]byte(xml.Header)) },
        func () { _, err = out.Write(data) },
        func () { _, err = out.Write([]byte("\n")) }} {
        action();
        if err != nil {
            return err
        }
    }
    return nil;
}

The example iterates over an array of functions to unify the error handling for the functions. A complete example is at Google´s playground.

PS: it shows also that hanging braces are a bad idea for the readability of code. Hint: the for condition ends just before the action() call. Obvious, isn't it?

Solution 5 - Go

You can in fact use range without referencing it's return values by using for range against your type:

arr := make([]uint8, 5)
i,j := 0,0
for range arr {
	fmt.Println("Array Loop",i)
	i++
}

for range "bytes" {
	fmt.Println("String Loop",j)
	j++
}

https://play.golang.org/p/XHrHLbJMEd

Solution 6 - Go

Yes, Range :

The range form of the for loop iterates over a slice or map.

When ranging over a slice, two values are returned for each iteration. The first is the index, and the second is a copy of the element at that index.

Example :

package main

import "fmt"

var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {
	for i, v := range pow {
		fmt.Printf("2**%d = %d\n", i, v)
	}
	
	for i := range pow {
		pow[i] = 1 << uint(i) // == 2**i
	}
	for _, value := range pow {
		fmt.Printf("%d\n", value)
	}
}
  • You can skip the index or value by assigning to _.
  • If you only want the index, drop the , value entirely.

Solution 7 - Go

This may be obvious, but you can inline the array like so:

package main

import (
	"fmt"
)

func main() {
	for _, element := range [3]string{"a", "b", "c"} {
		fmt.Print(element)
	}
}

outputs:

abc

https://play.golang.org/p/gkKgF3y5nmt

Solution 8 - Go

I have jus implement this library:https://github.com/jose78/go-collection. This is an example about how to use the Foreach loop:

package main

import (
	"fmt"

	col "github.com/jose78/go-collection/collections"
)

type user struct {
	name string
	age  int
	id   int
}

func main() {
	newList := col.ListType{user{"Alvaro", 6, 1}, user{"Sofia", 3, 2}}
	newList = append(newList, user{"Mon", 0, 3})

	newList.Foreach(simpleLoop)
	
	if err := newList.Foreach(simpleLoopWithError); err != nil{
		fmt.Printf("This error >>> %v <<< was produced", err )	
	}
}

var simpleLoop col.FnForeachList = func(mapper interface{}, index int) {
	fmt.Printf("%d.- item:%v\n", index, mapper)
}


var simpleLoopWithError col.FnForeachList = func(mapper interface{}, index int) {
	if index > 1{
		panic(fmt.Sprintf("Error produced with index == %d\n", index))
	}
	fmt.Printf("%d.- item:%v\n", index, mapper)
}

The result of this execution should be:

0.- item:{Alvaro 6 1}
1.- item:{Sofia 3 2}
2.- item:{Mon 0 3}
0.- item:{Alvaro 6 1}
1.- item:{Sofia 3 2}
Recovered in f Error produced with index == 2

ERROR: Error produced with index == 2
This error >>> Error produced with index == 2
 <<< was produced

Try this code in playGrounD

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontatsuhirosatouView Question on Stackoverflow
Solution 1 - GoKeith ThompsonView Answer on Stackoverflow
Solution 2 - GoZippoView Answer on Stackoverflow
Solution 3 - GoNisal EduView Answer on Stackoverflow
Solution 4 - GocevingView Answer on Stackoverflow
Solution 5 - GorobstarbuckView Answer on Stackoverflow
Solution 6 - GoAmitesh BhartiView Answer on Stackoverflow
Solution 7 - GojpihlView Answer on Stackoverflow
Solution 8 - GoJose78View Answer on Stackoverflow