Sorting is a very common use case that we encounter in day-to-day programming. In this article, you’ll learn how to sort a slice of primitive types (string, int, float64) and user-defined collections in Go.

## Sorting a Slice of Strings, Integers, or Floats in Go

The sort package in Go provides several convenience methods for sorting a slice of primitive types. The following example demonstrates how to sort a slice of strings, integers, and floats in Go:

``````package main

import (
"fmt"
"sort"
)

func main() {
// Sorting a slice of Strings
strs := []string{"quick", "brown", "fox", "jumps"}
sort.Strings(strs)
fmt.Println("Sorted strings: ", strs)

// Sorting a slice of Integers
ints := []int{56, 19, 78, 67, 14, 25}
sort.Ints(ints)
fmt.Println("Sorted integers: ", ints)

// Sorting a slice of Floats
floats := []float64{176.8, 19.5, 20.8, 57.4}
sort.Float64s(floats)
fmt.Println("Sorted floats: ", floats)
}``````
``````\$ go run sorting.go
Sorted strings:  [brown fox jumps quick]
Sorted integers:  [14 19 25 56 67 78]
Sorted floats:  [19.5 20.8 57.4 176.8]``````

### Sorting a Slice in Reverse order

To sort a slice in reverse order, you can use the `Reverse()` function along with `StringSlice`, `IntSlice`, and `Float64Slice` types. These types implement the `Interface` for comparision and swap defined in the `sort` package.

The `Reverse()` function returns the reverse order of data. Let’s look at an example of sorting a slice of strings, integers, and floats in reverse order:

``````package main

import (
"fmt"
"sort"
)

func main() {
// Sorting a slice of Strings
strs := []string{"quick", "brown", "fox", "jumps"}
sort.Sort(sort.Reverse(sort.StringSlice(strs)))
fmt.Println("Sorted strings in reverse order: ", strs)

// Sorting a slice of Integers
ints := []int{56, 19, 78, 67, 14, 25}
sort.Sort(sort.Reverse(sort.IntSlice(ints)))
fmt.Println("Sorted integers in reverse order: ", ints)

// Sorting a slice of Floats
floats := []float64{176.8, 19.5, 20.8, 57.4}
sort.Sort(sort.Reverse(sort.Float64Slice(floats)))
fmt.Println("Sorted floats in reverse order: ", floats)
}``````
``````\$ go run reverse-sorting.go
Sorted strings in reverse order:  [quick jumps fox brown]
Sorted integers in reverse order:  [78 67 56 25 19 14]
Sorted floats in reverse order:  [176.8 57.4 20.8 19.5]``````

## Sorting a slice using a comparator function in Go

Many times, you would want to sort a collection by something other than its natural order. For example, you would want to sort a slice of strings by their length, or you would want to sort a slice of users by their age.

For these usecases, you can use the `Slice()` and `SliceStable()` functions provided by the `sort` package. These are higher order functions that accept a `less` function as an argument:

``````func Slice(x interface{}, less func(i, j int) bool)
func SliceStable(x interface{}, less func(i, j int) bool)``````

The `less` function is a comparator function that reports whether the element at index `i` should sort before the element at index `j`. If both `less(i, j)` and `less(j, i)` are false, then the elements at index `i` and `j` are considered equal.

When you use the `Slice()` function, the sort is not guaranteed to be stable: equal elements may be reversed from their original order. For a stable sort, use `SliceStable()`.

Let’s look at an example:

``````package main

import (
"fmt"
"sort"
)

func main() {
// Sorting a slice of strings by length
strs := []string{"United States", "India", "France", "United Kingdom", "Spain"}
sort.Slice(strs, func(i, j int) bool {
return len(strs[i]) < len(strs[j])
})
fmt.Println("Sorted strings by length: ", strs)

// Stable sort
sort.SliceStable(strs, func(i, j int) bool {
return len(strs[i]) < len(strs[j])
})
fmt.Println("[Stable] Sorted strings by length: ", strs)

// Sorting a slice of strings in the reverse order of length
sort.SliceStable(strs, func(i, j int) bool {
return len(strs[j]) < len(strs[i])
})
fmt.Println("[Stable] Sorted strings by reverse order of length: ", strs)
}``````
``````\$ go run sorting-by-comparator.go
Sorted strings by length:  [India Spain France United States United Kingdom]
[Stable] Sorted strings by length:  [India Spain France United States United Kingdom]
[Stable] Sorted strings by reverse order of length:  [United Kingdom United States France India Spain]``````

### Sorting a slice of structs using a comparator function

This is a continuation of the previous example. This example demonstrates how to sort a collection of user-defined structs by passing a custom `less` function to the `Slice()` and `SliceStable()` functions:

``````package main

import (
"fmt"
"sort"
)

type User struct {
Name string
Age  int
}

func main() {
// Sorting a slice of structs by a field
users := []User{
{
Name: "Rajeev",
Age:  28,
},
{
Name: "Monica",
Age:  31,
},
{
Name: "John",
Age:  56,
},
{
Name: "Amanda",
Age:  16,
},
{
Name: "Steven",
Age:  28,
},
}

// Sort users by their age
sort.Slice(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})
fmt.Println("Sorted users by age: ", users)

// Stable sort
sort.SliceStable(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})
fmt.Println("Sorted users by age: ", users)
}``````

## Custom sorting by implementing sort.Interface

Finally, let’s look at the most generic way of sorting a collection of primitives or user-defined structs in Go. To enable custom sorting of a collection of any type, you need to define a corresponding type that implements the generic `Interface` provided by the `sort` package. The `Interface` contains the following methods:

``````type Interface interface {
// Len is the number of elements in the collection.
Len() int

// Less reports whether the element with index i must sort before the element with index j.
// If both Less(i, j) and Less(j, i) are false, then the elements at index i and j are considered equal.
Less(i, j int) bool

// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}``````

After implementing the above `Interface`, you can use the `Sort()` or `Stable()` functions that sort any collection that implements the `sort.Interface` interface.

Let’s understand with an example:

``````package main

import (
"fmt"
"sort"
)

type User struct {
Name string
Age  int
}

// Define a collection type that implements sort.Interface
type UsersByAge []User

func (u UsersByAge) Len() int {
return len(u)
}
func (u UsersByAge) Swap(i, j int) {
u[i], u[j] = u[j], u[i]
}
func (u UsersByAge) Less(i, j int) bool {
return u[i].Age < u[j].Age
}

func main() {
users := []User{
{
Name: "Rajeev",
Age:  28,
},
{
Name: "Monica",
Age:  31,
},
{
Name: "John",
Age:  56,
},
{
Name: "Amanda",
Age:  16,
},
{
Name: "Steven",
Age:  28,
},
}

// Sorting a slice of users by age (Sort may place equal elements in any order in the final result)
sort.Sort(UsersByAge(users))
fmt.Println("Sorted users by age: ", users)

// Stable Sorting (Stavle sort preserves the original input order of equal elements)
sort.Stable(UsersByAge(users))
fmt.Println("[Stable] Sorted users by age: ", users)

}``````
``````\$ go run custom-sorting-struct.go
Sorted users by age:  [{Amanda 16} {Rajeev 28} {Steven 28} {Monica 31} {John 56}]
[Stable] Sorted users by age:  [{Amanda 16} {Rajeev 28} {Steven 28} {Monica 31} {John 56}]``````