Модульні уроки (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Якщо елемента немає, він повертає індекс вставки. Можна копати в деталі, коли вони вам потрібні.
Generics (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` сортує зріз int на місці.
Рішення доступне після 3 спроб
Сортуйте людей за віком у порядку зростання за допомогою sort.Slice.
Показати підказку
Функція less повертає істину, коли елемент 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). - Для ключів карти: витягніть у фрагмент і відсортуйте.