How do I reverse an array in Go?
http://play.golang.org/p/W70J4GU7nA
s := []int{5, 2, 6, 3, 1, 4}
sort.Reverse(sort.IntSlice(s))
fmt.Println(s)
// 5, 2, 6, 3, 1, 4
It is hard to understand what it means in func Reverse(data Interface) Interface .
How do I reverse an array? I do not need to sort.
Honestly this one is simple enough that I'd just write it out like this:
package main
import "fmt"
func main() {
s := []int{5, 2, 6, 3, 1, 4}
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
fmt.Println(s)
}
http://play.golang.org/p/vkJg_D1yUb
(The other answers do a good job of explaining sort.Interface
and how to use it; so I won't repeat that.)
Normally, to sort an array of integers you wrap them in an IntSlice
, which defines the methods Len
, Less
, and Swap
. These methods are in turn used by sort.Sort
. What sort.Reverse
does is that it takes an existing type that defines Len
, Less
, and Swap
, but it replaces the Less
method with a new one that is always the inverse of the underlying Less
:
type reverse struct {
// This embedded Interface permits Reverse to use the methods of
// another Interface implementation.
Interface
}
// Less returns the opposite of the embedded implementation's Less method.
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
// Reverse returns the reverse order for data.
func Reverse(data Interface) Interface {
return &reverse{data}
}
So when you write sort.Reverse(sort.IntSlice(s))
, whats happening is that you're getting this new, 'modified' IntSlice
that has it's Less
method replaced. So if you call sort.Sort
on it, which calls Less
, it will get sorted in decreasing order.
I'm 2 years late, but just for fun and interest I'd like to contribute an "oddball" solution.
Assuming the task really is to reverse a list, then for raw performance bgp's solution is probably unbeatable. It gets the job done simply and effectively by swapping array items front to back, an operation that's efficient in the random-access structure of arrays and slices.
In Functional Programming languages, the idiomatic approach would often involve recursion. This looks a bit strange in Go and will have atrocious performance. That said, here's a recursive array reversal function (in a little test program):
package main
import (
"fmt"
)
func main() {
myInts := []int{ 8, 6, 7, 5, 3, 0, 9 }
fmt.Printf("Ints %v reversed: %v\n", myInts, reverseInts(myInts))
}
func reverseInts(input []int) []int {
if len(input) == 0 {
return input
}
return append(reverseInts(input[1:]), input[0])
}
Output:
Ints [8 6 7 5 3 0 9] reversed: [9 0 3 5 7 6 8]
Again, this is for fun and not production. Not only is it slow, but it will overflow the stack if the list is too large. I just tested, and it will reverse a list of 1 million int
s but crashes on 10 million.
First of all, if you want to reverse the array, do like this,
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
Then, look at the usage of Reverse in golang.org
package main
import (
"fmt"
"sort"
)
func main() {
s := []int{5, 2, 6, 3, 1, 4} // unsorted
sort.Sort(sort.Reverse(sort.IntSlice(s)))
fmt.Println(s)
}
// output
// [6 5 4 3 2 1]
And look at the description of Reverse and Sort
func Reverse(data Interface) Interface
func Sort(data Interface)
Sort sorts data. It makes one call to data.Len to determine n, and O(n*log(n)) calls to data.Less and data.Swap. The sort is not guaranteed to be stable.
So, as you know, Sort is not just a sort algorithm, you can view it as a factory, when you use Reverse it just return a reversed sort algorithm, Sort is just doing the sorting.
This is a more generic slice reverse function. It will panic if input is not a slice.
//panic if s is not a slice
func ReverseSlice(s interface{}) {
size := reflect.ValueOf(s).Len()
swap := reflect.Swapper(s)
for i, j := 0, size-1; i < j; i, j = i+1, j-1 {
swap(i, j)
}
}