Logo
Книга для начинающих
ВходРегистрация
/
Программирование
/
Курс 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}] — оригинал не изменился
Коммерческий опыт и Трудоустройство

Полезное

  • Функция slices.Sort()

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

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются
/
Программирование
/
Курс 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}] — оригинал не изменился
Коммерческий опыт и Трудоустройство

Полезное

  • Функция slices.Sort()

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

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

Ваше упражнение проверяется по этим тестам

// Тесты
package solution

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestSortOrdersByCustomerID(t *testing.T) {
	tests := []struct {
		name     string
		input    []Order
		expected []Order
	}{
		{
			name: "Sort by CustomerID",
			input: []Order{
				{CustomerID: 3, Price: 200},
				{CustomerID: 1, Price: 300},
				{CustomerID: 2, Price: 100},
			},
			expected: []Order{
				{CustomerID: 1, Price: 300},
				{CustomerID: 2, Price: 100},
				{CustomerID: 3, Price: 200},
			},
		},
		{
			name: "Sort by CustomerID and price",
			input: []Order{
				{CustomerID: 2, Price: 300},
				{CustomerID: 2, Price: 100},
				{CustomerID: 1, Price: 500},
			},
			expected: []Order{
				{CustomerID: 1, Price: 500},
				{CustomerID: 2, Price: 100},
				{CustomerID: 2, Price: 300},
			},
		},
		{
			name:     "Empty slice",
			input:    []Order{},
			expected: []Order{},
		},
		{
			name:     "Single element",
			input:    []Order{{CustomerID: 1, Price: 100}},
			expected: []Order{{CustomerID: 1, Price: 100}},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := SortOrdersByCustomerID(tt.input)
			assert.Equal(t, tt.expected, result)
			assert.Equal(t, tt.input, tt.input, "original slice should remain unchanged")
		})
	}
}
← ПредыдущийСледующий →

Решение учителя откроется через:

20:00

waiting_clock
← ПредыдущийСледующий →