Skip to main content
eLearner.app
Module 4 · Lesson 5 of 520/50 in the course~10 min
Module lessons (5/5)

Sorting with the sort package

The standard sort package sorts slices in-place. For base types (int, float64, string) there are direct helpers; for any other slice you use sort.Slice with a less(i, j int) bool function that defines the ordering.

Helpers for base types

Go
import "sort"

nums := []int{5, 2, 8, 1}
sort.Ints(nums)        // [1 2 5 8]

words := []string{"c", "a", "b"}
sort.Strings(words)    // [a b c]

fs := []float64{1.5, 0.5, 2.5}
sort.Float64s(fs)      // [0.5 1.5 2.5]

The sort is in-place: the original slice is mutated.

sort.Slice: custom sorting

You pass the slice and a less function that, given two indices i and j, returns true if element i should come before j:

Go
type Person struct {
    Name string
    Age  int
}

people := []Person{
    {"Bruno", 30},
    {"Anna", 25},
    {"Carla", 28},
}

sort.Slice(people, func(i, j int) bool {
    return people[i].Age < people[j].Age
})
// Anna(25), Carla(28), Bruno(30)

To sort in reverse, just flip the comparison: return people[i].Age > people[j].Age.

Stable sort

sort.Slice is not guaranteed to be stable ("equal" elements may change relative order). For a stable sort use sort.SliceStable:

Go
sort.SliceStable(people, func(i, j int) bool {
    return people[i].Age < people[j].Age
})

Sorting by multiple keys

Common pattern: sort by age, and for equal ages by name:

Go
sort.Slice(people, func(i, j int) bool {
    if people[i].Age != people[j].Age {
        return people[i].Age < people[j].Age
    }
    return people[i].Name < people[j].Name
})

Binary search

sort.SearchInts / sort.Search work on already-sorted slices:

Go
nums := []int{1, 3, 5, 7, 9}
i := sort.SearchInts(nums, 5)   // 2

If the element isn't there, it returns the insertion index. You can dig into the details when you need them.

Generics (Go 1.21+): slices.Sort

From the slices package in stdlib (Go 1.21):

Go
import "slices"

nums := []int{3, 1, 2}
slices.Sort(nums)               // [1 2 3]
slices.SortFunc(people, func(a, b Person) int {
    return a.Age - b.Age        // -1/0/1
})

More modern, type-safe API. Compatible with sort.Slice but more ergonomic.

Try it

Exercise#go.m4.l5.e1
Attempts: 0Loading…

Sort nums in ascending order using sort.Ints.

Loading editor…
Show hint

`sort.Ints` sorts an int slice in-place.

Solution available after 3 attempts

Exercise#go.m4.l5.e2
Attempts: 0Loading…

Sort people by Age in ascending order using sort.Slice.

Loading editor…
Show hint

The less function returns true when element i should come BEFORE j.

Solution available after 3 attempts

Quiz#go.m4.l5.e3
Ready

How do you sort in descending order with sort.Slice?

Go
sort.Slice(s, func(i, j int) bool { return ??? })
Answer options

Recap

  • sort.Ints / sort.Strings / sort.Float64s for base types, in-place.
  • sort.Slice(s, less) for slices of any type, with a less(i, j) function.
  • sort.SliceStable to preserve relative order for equal keys.
  • Sorting by multiple keys: a cascade of ifs inside less.
  • Go 1.21+: slices package with a generic API (slices.Sort, slices.SortFunc).
  • For map keys: extract into a slice and sort.