/
Программирование
/
Курс Golang
/

Сортировка срезов

Golang: Сортировка срезов

Сортировка — одна из самых распространённых операций над коллекциями. В Go для работы со срезами предусмотрены готовые функции в пакете slices, которые упрощают сортировку без необходимости писать собственные алгоритмы.

Сортировка по возрастанию

Для сортировки среза с элементами любого упорядоченного типа (например, int, string) используется функция slices.Sort():

import (
	"fmt"
	"slices"
)

func main() {
	nums := []int{5, 2, 9, 1, 3}
	slices.Sort(nums)
	fmt.Println(nums) // => [1 2 3 5 9]
}

Изменяется ли исходный срез?

Важно помнить, что slices.Sort() изменяет исходный срез на месте. После вызова slices.Sort(nums) срез nums будет отсортирован, а новый срез не создаётся. Если нужно получить новый отсортированный срез, используйте slices.Sorted(), которая возвращает копию с отсортированными элементами:

original := []int{5, 2, 9}
sorted := slices.Sorted(original)

fmt.Println(original)
// => [5 2 9]
fmt.Println(sorted)
// => [2 5 9]

Проверка, отсортирован ли срез

Иногда нужно проверить, находится ли срез в порядке возрастания. Для этого есть slices.IsSorted():

nums := []int{1, 2, 3}
fmt.Println(slices.IsSorted(nums)) // => true

Сортировка строк

Срез строк сортируется аналогично:

words := []string{"banana", "apple", "cherry"}
slices.Sort(words)
fmt.Println(words) // => [apple banana cherry]

Сортировка выполняется в лексикографическом порядке (по Unicode-кодам символов).

Сортировка с пользовательской логикой

Если нужно задать собственное правило сортировки, можно использовать slices.SortFunc(). Например, сортировка строк по длине:

slices.SortFunc(words, func(a, b string) int {
	// по длине
	return len(a) - len(b)
})
fmt.Println(words) // => [apple banana cherry]

Функция-компаратор должна возвращать:

  • Отрицательное значение, если a < b,
  • Ноль, если a == b,
  • Положительное значение, если a > b.

Обратный порядок

Чтобы отсортировать в обратном порядке, можно:

  1. Отсортировать по возрастанию.
  2. Развернуть срез с помощью slices.Reverse().
nums := []int{5, 2, 9, 1, 3}
slices.Sort(nums)
slices.Reverse(nums)
fmt.Println(nums) // => [9 5 3 2 1]

Минимальные и максимальные значения

Пакет slices также предоставляет функции для нахождения минимального и максимального элементов:

nums := []int{5, 2, 9, 1, 3}
fmt.Println(slices.Min(nums)) // => 1
fmt.Println(slices.Max(nums)) // => 9

Вывод

  • Функции slices.Sort() и slices.SortFunc() изменяют исходный срез.
  • Если нужен новый отсортированный срез, используйте slices.Clone() перед сортировкой.
  • Для кастомных правил сортировки — slices.SortFunc().
  • Проверить порядок можно через slices.IsSorted().
  • Минимум и максимум вычисляются с помощью slices.Min() и slices.Max().

Задание

Реализуйте функцию SortOrdersByCustomerID(orders []Order) []Order, которая возвращает новый срез заказов, отсортированных по ID клиента (от меньшего к большему). Если у нескольких заказов одинаковый CustomerID — сортируйте их по цене (от меньшей к большей).

Структура Order уже определена:

type Order struct {
	CustomerID int
	Price      int
}

Оригинальный срез изменяться не должен.

Примеры:

orders := []Order{
	{CustomerID: 3, Price: 200},
	{CustomerID: 1, Price: 300},
	{CustomerID: 3, Price: 100},
}

result := SortOrdersByCustomerID(orders)
fmt.Println(result)
// [{1 300} {3 100} {3 200}]
fmt.Println(orders)
// [{3 200} {1 300} {3 100}] — оригинал не изменился

Полезное

Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются