A guide to sorting in Go
Programming languages often provide ready-made helpers for sorting collections due to the incredibly common nature of this task. Go is no different with its provision of the sort package for all your sorting needs.
Sorting data is one of the most common tasks you may find yourself performing ever so often. This article explores a few techniques in Go that should make the sorting of any data collection a breeze.
Sort a slice of strings
The sort.Strings
method sorts a slice of strings in increasing order as shown
below:
func main() {
s := []string{"James", "John", "Peter", "Andrew", "Matthew", "Luke"}
sort.Strings(s)
fmt.Println(s) // [Andrew James John Luke Matthew Peter]
}
The sort.StringsAreSorted
method also exists to help you check if a string
slice is in its sorted form (that is, in increasing order):
func main() {
s := []string{"James", "John", "Peter", "Andrew", "Matthew", "Luke"}
fmt.Println(sort.StringsAreSorted(s)) // false
sort.Strings(s)
fmt.Println(sort.StringsAreSorted(s)) // true
}
Sort a slice of integers
To sort a slice of integers, use the sort.Ints
method as shown below:
func main() {
intSlice := []int{4, 5, 2, 1, 3, 9, 7, 8, 6}
fmt.Println(sort.IntsAreSorted(intSlice)) // false
sort.Ints(intSlice)
fmt.Println(intSlice) // [1 2 3 4 5 6 7 8 9]
fmt.Println(sort.IntsAreSorted(intSlice)) // true
}
Sort a slice of floats
A slice of float64s may be sorted in increasing order using sort.Float64s
:
func main() {
f := []float64{math.NaN(), -0.2, -1.3, 0.9, 4.8, 2.1}
fmt.Println(sort.Float64sAreSorted(f)) // false
sort.Float64s(f)
fmt.Println(f) // [NaN -1.3 -0.2 0.9 2.1 4.8]
fmt.Println(sort.Float64sAreSorted(f)) // true
}
Sort a slice of structs
To sort a slice of structs in Go, you need to use a less
function along with
either the sort.Slice
or sort.SliceStable
methods. Here’s how we can sort a
slice of persons according to their names and ages for example:
type Person struct {
name string
age int
}
func main() {
{%raw %}people := []Person{{"Sally", 20}, {"David", 40}, {"Jon", 30}, {"Larry", 25}}{% endraw %}
sort.SliceStable(people, func(i, j int) bool {
return people[i].age < people[j].age
})
fmt.Println("Sorted by age:", people)
sort.SliceStable(people, func(i, j int) bool {
return people[i].name < people[j].name
})
fmt.Println("Sorted by name:", people)
}
Returning true
from the less
function will cause the element at index i
to
be sorted to a lower position than index j
(The element at index i
will come
first in the sorted slice). Otherwise, the element at index j
will come first
if false
is returned.
The difference between sort.Slice
and sort.SliceStable
is that the latter
will keep the original order of equal elements while the former may not.
Sort a struct slice using multiple keys
In the example below, a slice of Person
structs is sorted by LastName
, and
then by FirstName
so that if two people have the same LastName
, they’ll be
ordered according to their FirstName
.
type Person struct {
FirstName string
LastName string
}
func main() {
people := []Person{
{"Michael", "Jackson"},
{"Janet", "Jackson"},
{"Keanu", "Reeves"},
{"Reverend", "King"},
{"Jane", "Austen"},
}
sort.SliceStable(people, func(i, j int) bool {
if people[i].LastName != people[j].LastName {
return people[i].LastName < people[j].LastName
}
return people[i].FirstName < people[j].FirstName
})
fmt.Println(people)
}
Notice how Janet Jackson comes before Michael Jackson in the output.
Sort a map by key or value
Maps are unordered collections in Go so there is no provision for sorting a
map using the sort
package. However, if you really need to sort a map, you can
try the methods described below.
From Go 1.12, you can print the map and it’ll be sorted by keys:
func main() {
m := map[string]int{
"sally": 45,
"john": 5,
"marcy": 15,
"duff": 10,
"tom": 20,
}
fmt.Println(m) // map[duff:10 john:5 marcy:15 sally:45 tom:20]
}
If you intend to do more than just printing the map or if you want to sort by value instead, you should use the methods described in this article to guarantee the iterate order of the map.
Conclusion
Sorting collections of data is pretty straightforward in Go through the use of
the sort
package and the solutions presented above should suffice for the
majority of situations you will face. If you know of a different way to sort
that is not covered in this article, do share it in the comments section
below.
Thanks for reading, and happy coding!