Уроки модуля (5/5)
Сортировка с помощью пакета sort
Стандартный пакет sort сортирует фрагменты на месте. Для базовых типов
(int, float64, string) есть прямые помощники; за любой другой кусочек тебя
используйте sort.Slice с функцией less(i, j int) bool, которая определяет
заказ.
Помощники для базовых типов
import "sort"
nums := []int{5, 2, 8, 1}
sort.Ints(nums) // [1 2 5 8]
words := []string{"c", "a", "b"}
sort.Strings(words) // [a b c]
fs := []float64{1.5, 0.5, 2.5}
sort.Float64s(fs) // [0.5 1.5 2.5]Сортировка осуществляется на месте: исходный фрагмент мутирует.
sort.Slice: пользовательская сортировка
Вы передаете срез и функцию less, которая, учитывая два индекса i и
j возвращает true, если элемент i должен предшествовать j:
type Person struct {
Name string
Age int
}
people := []Person{
{"Bruno", 30},
{"Anna", 25},
{"Carla", 28},
}
sort.Slice(people, func(i, j int) bool {
return people[i].Age < people[j].Age
})
// Anna(25), Carla(28), Bruno(30)Чтобы отсортировать в обратном порядке, просто переверните сравнение:
return people[i].Age > people[j].Age.
Стабильная сортировка
sort.Slice не гарантирует стабильность (равные элементы могут меняться).
относительный порядок). Для стабильной сортировки используйте sort.SliceStable:
sort.SliceStable(people, func(i, j int) bool {
return people[i].Age < people[j].Age
})Сортировка по нескольким ключам
Общий шаблон: сортировка по возрасту и для одинаковых возрастов по имени:
sort.Slice(people, func(i, j int) bool {
if people[i].Age != people[j].Age {
return people[i].Age < people[j].Age
}
return people[i].Name < people[j].Name
})Бинарный поиск
sort.SearchInts / sort.Search работают с уже отсортированными фрагментами:
nums := []int{1, 3, 5, 7, 9}
i := sort.SearchInts(nums, 5) // 2Если элемента нет, он возвращает индекс вставки. Вы можете копать в детали, когда они вам нужны.
Дженерики (Go 1.21+): slices.Sort
Из пакета slices в stdlib (Go 1.21):
import "slices"
nums := []int{3, 1, 2}
slices.Sort(nums) // [1 2 3]
slices.SortFunc(people, func(a, b Person) int {
return a.Age - b.Age // -1/0/1
})Более современный, типобезопасный API. Совместим с sort.Slice и более
эргономичный.
Попробуйте это
Сортируйте числа в порядке возрастания, используя sort.Ints.
Показать подсказку
`sort.Ints` сортирует фрагмент целого числа на месте.
Решение доступно после 3 попыток
Сортируйте людей по возрасту в порядке возрастания с помощью sort.Slice.
Показать подсказку
Функция less возвращает true, когда элемент i должен появиться ДО j.
Решение доступно после 3 попыток
Как выполнить сортировку по убыванию с помощью sort.Slice?
sort.Slice(s, func(i, j int) bool { return ??? })Резюме
sort.Ints/sort.Strings/sort.Float64sдля базовых типов, на месте.sort.Slice(s, less)для фрагментов любого типа с функциейless(i, j).sort.SliceStableдля сохранения относительного порядка одинаковых ключей.- Сортировка по нескольким ключам: каскад
ifвнутриless. - Перейти 1.21+: пакет
slicesс общим API (slices.Sort,slices.SortFunc). - Для ключей карты: извлеките на срез и отсортируйте.