Golang slices.SortFunc
last modified April 20, 2025
This tutorial explains how to use the slices.SortFunc
function in Go.
We'll cover custom sorting of slices with practical examples.
The slices.SortFunc function sorts a slice using a custom comparison function. It's part of Go's experimental slices package.
This function provides flexible sorting when built-in ordering isn't sufficient. It allows sorting by any criteria you define in your comparison function.
Basic slices.SortFunc Example
The simplest use of slices.SortFunc
sorts integers in descending
order. We define a comparison function that reverses the normal order.
package main import ( "fmt" "slices" ) func main() { numbers := []int{3, 1, 4, 1, 5, 9, 2, 6} slices.SortFunc(numbers, func(a, b int) int { return b - a // For descending order }) fmt.Println("Sorted numbers:", numbers) }
The comparison function returns a positive number when a should come after b. This results in a descending sort of the integer slice.
Sorting Strings by Length
slices.SortFunc
can sort strings by length instead of lexicographical
order. This example shows how to implement custom string sorting.
package main import ( "fmt" "slices" ) func main() { words := []string{"apple", "banana", "kiwi", "orange"} slices.SortFunc(words, func(a, b string) int { return len(a) - len(b) }) fmt.Println("Sorted by length:", words) }
The comparison function subtracts string lengths to determine order. Shorter strings appear first in the sorted result.
Sorting Structs by Field
We can use slices.SortFunc
to sort structs by specific fields.
This example sorts people by age.
package main import ( "fmt" "slices" ) type Person struct { Name string Age int } func main() { people := []Person{ {"Alice", 25}, {"Bob", 30}, {"Charlie", 20}, } slices.SortFunc(people, func(a, b Person) int { return a.Age - b.Age }) fmt.Println("Sorted by age:", people) }
The comparison function accesses the Age field of each struct. The result is sorted from youngest to oldest person.
Case-Insensitive String Sorting
This example demonstrates case-insensitive sorting of strings using
slices.SortFunc
.
package main import ( "fmt" "slices" "strings" ) func main() { words := []string{"Apple", "banana", "cherry", "apricot"} slices.SortFunc(words, func(a, b string) int { return strings.Compare(strings.ToLower(a), strings.ToLower(b)) }) fmt.Println("Case-insensitive sort:", words) }
The comparison converts both strings to lowercase before comparing. This ensures sorting ignores case differences between words.
Multi-Field Sorting
slices.SortFunc
can implement complex sorting criteria. This example
sorts by multiple fields (last name then first name).
package main import ( "fmt" "slices" "strings" ) type Person struct { First string Last string } func main() { people := []Person{ {"John", "Doe"}, {"Alice", "Smith"}, {"Bob", "Smith"}, {"Alice", "Adams"}, } slices.SortFunc(people, func(a, b Person) int { if cmp := strings.Compare(a.Last, b.Last); cmp != 0 { return cmp } return strings.Compare(a.First, b.First) }) fmt.Println("Sorted people:", people) }
The comparison first checks last names, then falls back to first names if last names are equal. This creates a natural multi-field sort order.
Custom Order Sorting
This example shows how to sort elements according to a custom priority order rather than natural ordering.
package main import ( "fmt" "slices" ) func main() { colors := []string{"red", "blue", "green", "red", "blue"} priority := map[string]int{"red": 1, "blue": 2, "green": 3} slices.SortFunc(colors, func(a, b string) int { return priority[a] - priority[b] }) fmt.Println("Sorted by priority:", colors) }
The comparison uses a priority map to define the sort order. Red appears first, followed by blue, then green in the sorted result.
Stable Sorting
While slices.SortFunc
isn't stable by default, we can implement
stability by including original indices in the comparison.
package main import ( "fmt" "slices" ) func main() { items := []struct { Value int Index int }{ {3, 0}, {1, 1}, {2, 2}, {1, 3}, {3, 4}, } slices.SortFunc(items, func(a, b struct { Value int Index int }) int { if a.Value != b.Value { return a.Value - b.Value } return a.Index - b.Index }) fmt.Println("Stable sort result:", items) }
When values are equal, the comparison uses the original index to maintain order.
This achieves stable sorting behavior with slices.SortFunc
.
Source
Go experimental slices package documentation
This tutorial covered the slices.SortFunc
function in Go with practical
examples of custom sorting for various data types and scenarios.
Author
List all Go tutorials.