Przejdź do głównej treści
eLearner.app
Moduł 4 · Lekcja 5 z 520/50 w kursie~10 min
Lekcje modułu (5/5)

Sortowanie z pakietem sort

Standardowy pakiet sort sortuje plasterki na miejscu. Dla typów podstawowych (int, float64, string) istnieją bezpośrednie pomocniki; na jakikolwiek inny plasterek używasz sort.Slice z funkcją less(i, j int) bool, która definiuje sortowanie.

Pomocnik dla typów podstawowych

Go
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]

Sortowanie jest na miejscu: oryginalny plasterek jest zmutowany.

sort.Slice: sortowanie niestandardowe

Podajesz wycinek i funkcję less, która, biorąc pod uwagę dwa indeksy i i j, zwraca true, jeśli element i musi znajdować się przed j:

Go
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)

Aby posortować odwrotnie, po prostu zamień porównanie: return people[i].Age > people[j].Age.

Stabilne zamawianie

sort.Slice nie gwarantuje stabilności („te same” elementy mogą ulec zmianie porządek względny). Do stabilnego sortowania użyj sort.SliceStable:

Go
sort.SliceStable(people, func(i, j int) bool {
    return people[i].Age < people[j].Age
})

Sortowanie według wielu kluczy

Typowy wzorzec: sortuj według wieku i z tym samym wiekiem według imienia:

Go
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
})

Wyszukiwanie binarne

sort.SearchInts / sort.Search pracuj na już posortowanych plasterkach:

Go
nums := []int{1, 3, 5, 7, 9}
i := sort.SearchInts(nums, 5)   // 2

Jeżeli elementu tam nie ma, zwracany jest indeks wstawiania. Znajdziesz go w szczegóły, kiedy ich potrzebujesz.

Generics (wersja 1.21+): slices.Sort

Z pakietu slices stdlib (wersja 1.21):

Go
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
})

Bardziej nowoczesne i bezpieczne dla typów API. Kompatybilny z sort.Slice, ale nie tylko ergonomiczne.

Spróbuj sam

Ćwiczenie#go.m4.l5.e1
Próby: 0Ładowanie...

Sortuj liczby rosnąco za pomocą sort.Ints.

Ładowanie edytora...
Pokaż wskazówkę

`sort.Ints` sortuje wycinek typu int w miejscu.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie#go.m4.l5.e2
Próby: 0Ładowanie...

Sortuj ludzi według wieku rosnąco za pomocą metody sort.Slice.

Ładowanie edytora...
Pokaż wskazówkę

Funkcja less zwraca wartość true, gdy element i musi znajdować się PRZED j.

Rozwiązanie dostępne po 3 próbach

Quiz#go.m4.l5.e3
Gotowe

Jak sortować w kolejności malejącej za pomocą sort.Slice?

Go
sort.Slice(s, func(i, j int) bool { return ??? })
Opcje odpowiedzi

Podsumowanie

  • sort.Ints / sort.Strings / sort.Float64s dla podstawowych typów lokalnych.
  • sort.Slice(s, less) dla plasterków dowolnego typu, z funkcją less(i, j).
  • sort.SliceStable, aby zachować względną kolejność za pomocą tego samego klucza.
  • Sortowanie według wielu kluczy: kaskada if do less.
  • Przejdź do wersji 1.21+: pakiet slices z ogólnym API (slices.Sort, slices.SortFunc).
  • W przypadku kluczy mapy: wyodrębnij na plasterki i posortuj.