Go в примерах: Сортировка через функции (Sorting by Functions)

Иногда мы хотим отсортировать коллекцию по какому-то другому признаку, кроме ее естественного порядка. Например, предположим, что мы хотели бы отсортировать строки по длине, а не по алфавиту. Вот пример пользовательских сортировок в Go.

package main
import (
    "fmt"
    "sort"
)

Для сортировки по пользовательской функции в Go нам нужен соответствующий тип. Здесь мы создали тип byLength, который является просто псевдонимом для []string.

type byLength []string

Мы реализуем sort.Interface - Len,LessиSwap - для нашего типа, чтобы мы могли использовать общую функциюSortпакетаsort.LenиSwapобычно одинаковы для разных типов, аLessбудет содержать реальную пользовательскую логику сортировки. В нашем случае мы хотим отсортировать в порядке увеличения длины строки, поэтому мы используемlen(s[i])и len(s[j])` здесь.

func (s byLength) Len() int {
    return len(s)
}
func (s byLength) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}
func (s byLength) Less(i, j int) bool {
    return len(s[i]) < len(s[j])
}

Реализовав интерфейс, мы можем теперь реализовать нашу собственную сортировку, преобразовав исходный срез fruits в byLength, а затем использовать sort.Sort для этого типизированного среза.

func main() {
    fruits := []string{"peach", "banana", "kiwi"}
    sort.Sort(byLength(fruits))
    fmt.Println(fruits)
}

При запуске нашей программы отображается список, отсортированный по длине строки, как мы и хотели.

$ go run sorting-by-functions.go 
[kiwi peach banana]

Следуя той же схеме создания пользовательского типа, реализации трех методов интерфейса для этого типа и последующего вызова sort.Sort для коллекции этого типа, мы можем сортировать срезы Go по произвольным функциям.

Следующий пример: Panic.