Sorting by Functions

Сортировка через функции (Sorting by Functions)|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
# по произвольным функциям.