Is there a way to iterate over a slice in reverse in Go?

Go

Go Problem Overview


It would be convenient to be able to say something like:

for _, element := reverse range mySlice {
        ...
}

Go Solutions


Solution 1 - Go

No there is no convenient operator for this to add to the range one in place. You'll have to do a normal for loop counting down:

s := []int{5, 4, 3, 2, 1}
for i := len(s)-1; i >= 0; i-- {
   fmt.Println(s[i])
}

Solution 2 - Go

You can also do:

s := []int{5, 4, 3, 2, 1}
for i := range s {
        fmt.Println(s[len(s)-1-i]) // Suggestion: do `last := len(s)-1` before the loop
}

Output:

1
2
3
4
5

Also here: http://play.golang.org/p/l7Z69TV7Vl

Solution 3 - Go

Variation with index

for k := range s {
		k = len(s) - 1 - k
		// now k starts from the end
	}

Solution 4 - Go

How about use defer:

s := []int{5, 4, 3, 2, 1}
for i, _ := range s {
   defer fmt.Println(s[i])
}

Solution 5 - Go

One could use a channel to reverse a list in a function without duplicating it. It makes the code nicer in my sense.

package main

import (
	"fmt"
)

func reverse(lst []string) chan string {
	ret := make(chan string)
	go func() {
		for i, _ := range lst {
			ret <- lst[len(lst)-1-i]
		}
		close(ret)
	}()
	return ret
}

func main() {
	elms := []string{"a", "b", "c", "d"}
	for e := range reverse(elms) {
		fmt.Println(e)
	}
}

Solution 6 - Go

I guess this is the easiest way to reverse arrays.:

package main

import "fmt"

// how can we reverse write the array
func main() {

	arr := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	revArr := [len(arr)]int{} // making empty array for write reverse

	for i := range arr {
		revArr[len(arr)-1-i] = arr[i]
	}

	fmt.Println(revArr)
}

https://play.golang.org/p/QQhj26-FhtF

Solution 7 - Go

An elegant method for reverse range:

If your slice is transient: Loop while the number of elements is greater than zero, use the last element, and then remove it. The slice will be empty after the first element has been processed:

s := []int{1, 2, 3, 4}
for len(s) > 0 {
    item := s[len(s)-1]
    fmt.Printf("Reverse item: %+v\n", item)
    s = s[:len(s)-1]
}

Output:

Reverse item: 4
Reverse item: 3
Reverse item: 2
Reverse item: 1

Go Playground: https://play.golang.org/p/XKB43k7M9j3

Solution 8 - Go

When I need to extract elements from a slice and reverse range, I use something like this code:

// reverse range
// Go Playground: https://play.golang.org/p/gx6fJIfb7fo
package main

import (
	"fmt"
)

type Elem struct {
	Id   int64
	Name string
}

type Elems []Elem

func main() {
	mySlice := Elems{{Id: 0, Name: "Alice"}, {Id: 1, Name: "Bob"}, {Id: 2, Name: "Carol"}}
	for i, element := range mySlice {
		fmt.Printf("Normal  range: [%v] %+v\n", i, element)
	}

	//mySlice = Elems{}
	//mySlice = Elems{{Id: 0, Name: "Alice"}}
	if last := len(mySlice) - 1; last >= 0 {
		for i, element := last, mySlice[0]; i >= 0; i-- {
			element = mySlice[i]
			fmt.Printf("Reverse range: [%v] %+v\n", i, element)
		}
	} else {
		fmt.Println("mySlice empty")
	}
}

Output:

Normal  range: [0] {Id:0 Name:Alice}
Normal  range: [1] {Id:1 Name:Bob}
Normal  range: [2] {Id:2 Name:Carol}
Reverse range: [2] {Id:2 Name:Carol}
Reverse range: [1] {Id:1 Name:Bob}
Reverse range: [0] {Id:0 Name:Alice}

Playground: https://play.golang.org/p/gx6fJIfb7fo

Solution 9 - Go

You can use the funk.ForEachRight method from go-funk:

results := []int{}

funk.ForEachRight([]int{1, 2, 3, 4}, func(x int) {
    results = append(results, x)
})

fmt.Println(results) // []int{4, 3, 2, 1}

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
QuestionagamView Question on Stackoverflow
Solution 1 - GoUlf Holm NielsenView Answer on Stackoverflow
Solution 2 - GozzzzView Answer on Stackoverflow
Solution 3 - GoNicky FellerView Answer on Stackoverflow
Solution 4 - GoMattView Answer on Stackoverflow
Solution 5 - Gouser983716View Answer on Stackoverflow
Solution 6 - GoAlperen KILIÇView Answer on Stackoverflow
Solution 7 - GoDavid ManpearlView Answer on Stackoverflow
Solution 8 - GoVladimir FilinView Answer on Stackoverflow
Solution 9 - GoWoJView Answer on Stackoverflow