47 lines
2.0 KiB
Go
47 lines
2.0 KiB
Go
// Иногда мы хотим отсортировать коллекцию по какому-то
|
||
// другому признаку, кроме ее естественного порядка.
|
||
// Например, предположим, что мы хотели бы отсортировать
|
||
// строки по длине, а не по алфавиту. Вот пример
|
||
// пользовательских сортировок в 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)
|
||
}
|