Пользовательский порядок сортировки
Определяйте функции сравнения
«Пользовательский порядок сортировки» — бесплатный урок Go Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
За пределами порядка по умолчанию
По умолчанию сортировка выполняется по возрастанию. Но для реальных данных нужны собственные правила: сортировка по длине, по нескольким полям или по вычисляемому значению.
Функция сравнения позволяет выразить любое нужное Вам правило.
Функция сравнения
Функция сравнения для sort.Slice имеет сигнатуру func(i, j int) bool. Она возвращает true, когда элемент i должен находиться перед элементом j.
package main
import (
"fmt"
"sort"
)
func main() {
nums := []int{4, 1, 3}
less := func(i, j int) bool { return nums[i] < nums[j] }
sort.Slice(nums, less)
fmt.Println(nums)
}Сортировка по длине строк
Вместо алфавитного порядка сравнивайте значения len() каждой строки, чтобы упорядочить строки по длине.
package main
import (
"fmt"
"sort"
)
func main() {
words := []string{"pear", "fig", "banana"}
sort.Slice(words, func(i, j int) bool {
return len(words[i]) < len(words[j])
})
fmt.Println(words)
}Сортировка структур по полю
Для сравнения можно выбрать любое поле структуры. Здесь мы сортируем товары по цене.
package main
import (
"fmt"
"sort"
)
type Product struct {
Name string
Price int
}
func main() {
items := []Product{{"Pen", 3}, {"Book", 12}, {"Cup", 7}}
sort.Slice(items, func(i, j int) bool {
return items[i].Price < items[j].Price
})
fmt.Println(items)
}Сортировка по нескольким полям
Чтобы разрешить равенство, сравнивайте второе поле, если первое совпадает. Сортируйте по возрасту, а затем по имени.
package main
import (
"fmt"
"sort"
)
type Person struct {
Name string
Age int
}
func main() {
p := []Person{{"Zoe", 30}, {"Ann", 30}, {"Bob", 25}}
sort.Slice(p, func(i, j int) bool {
if p[i].Age != p[j].Age {
return p[i].Age < p[j].Age
}
return p[i].Name < p[j].Name
})
fmt.Println(p)
}Обратный порядок с помощью sort.Reverse
sort.Reverse оборачивает sort.Interface, меняя его порядок на обратный. Он используется вместе со вспомогательными функциями, такими как sort.IntSlice.
package main
import (
"fmt"
"sort"
)
func main() {
nums := []int{1, 4, 2, 3}
sort.Sort(sort.Reverse(sort.IntSlice(nums)))
fmt.Println(nums)
}Интерфейс sort.Interface
Для полного контроля реализуйте sort.Interface: три метода — Len(), Less(i, j int) bool и Swap(i, j int).
package main
import (
"fmt"
"sort"
)
type ByLen []string
func (s ByLen) Len() int { return len(s) }
func (s ByLen) Less(i, j int) bool { return len(s[i]) < len(s[j]) }
func (s ByLen) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func main() {
w := []string{"ccc", "a", "bb"}
sort.Sort(ByLen(w))
fmt.Println(w)
}Сортировка по вычисляемому значению
В сравнении можно использовать любое выражение. Сортируйте числа по их абсолютному расстоянию от нуля.
package main
import (
"fmt"
"sort"
)
func abs(n int) int {
if n < 0 {
return -n
}
return n
}
func main() {
nums := []int{-5, 2, -1, 3}
sort.Slice(nums, func(i, j int) bool {
return abs(nums[i]) < abs(nums[j])
})
fmt.Println(nums)
}Сортировка без учёта регистра
Используйте strings.ToLower внутри сравнения, чтобы не учитывать регистр при упорядочивании строк.
package main
import (
"fmt"
"sort"
"strings"
)
func main() {
w := []string{"banana", "Apple", "cherry"}
sort.Slice(w, func(i, j int) bool {
return strings.ToLower(w[i]) < strings.ToLower(w[j])
})
fmt.Println(w)
}Срез и интерфейс
Есть два способа настроить порядок:
sort.Slice— быстрая встроенная функция сравненияsort.Interface— повторно используемый именованный тип с тремя методами
Для разовой сортировки предпочитайте sort.Slice.
Сохраняйте сравнения чистыми
Функция сравнения должна только читать элементы и возвращать логическое значение. Она не должна изменять срез или иметь побочные эффекты, иначе сортировка может вести себя непредсказуемо.
Быстрая проверка
Вы хотите отсортировать людей по возрасту, а при одинаковом возрасте — по имени. Какой приём Вы используете?
Итоги
Вы можете задать любой порядок сортировки:
- Функция сравнения выражает Ваше правило
- При сортировке по нескольким полям при равенстве сравнивается второе поле
sort.Reverseменяет порядок на обратный;sort.Interfaceпредоставляет повторно используемые типы
Часто задаваемые вопросы
Урок «Пользовательский порядок сортировки» бесплатный?
Да — полный текст урока «Пользовательский порядок сортировки» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Пользовательский порядок сортировки»?
Определяйте функции сравнения Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Пользовательский порядок сортировки»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Сортировка срезов
- Пользовательский порядок сортировки
- Поиск в отсортированных данных
- Стабильная сортировка