Ce face sort.Slice
sort.Slice(x, less) sortează slice-ul x pe loc. Funcția less(i, j) primește doi indici și returnează true dacă elementul x[i] trebuie să stea înaintea lui x[j]. Așa sortezi structuri după orice câmp.
sort.Slice nu este stabilă: elementele considerate egale pot ieși în altă ordine decât au intrat. sort.SliceStable păstrează ordinea lor inițială, util când sortezi pe rând după mai multe criterii.
Varianta modernă este slices.SortFunc(x, cmp) (Go 1.21), care primește elementele, nu indicii, și o funcție de comparare ce returnează un număr negativ, zero sau pozitiv. Este verificată la compilare și de obicei mai rapidă.
Parametri
| Parametru | Descriere |
|---|---|
x |
Slice-ul de sortat (orice tip de slice; dacă nu este slice, programul se oprește cu panic). |
less |
Funcția care spune dacă elementul de la indicele i vine înaintea celui de la j. |
Ce returnează
Nimic; slice-ul este sortat pe loc.
Exemple
Exemplul 1: Elevi sortați după notă
package main
import (
"fmt"
"sort"
)
type Elev struct {
Nume string
Nota int
}
func main() {
elevi := []Elev{{"Ana", 9}, {"Mihai", 7}, {"Ioana", 10}, {"Radu", 8}}
sort.Slice(elevi, func(i, j int) bool {
return elevi[i].Nota > elevi[j].Nota // descrescător
})
for _, e := range elevi {
fmt.Println(e.Nume, e.Nota)
}
}
Rezultat
Ioana 10
Ana 9
Radu 8
Mihai 7
Exemplul 2: SliceStable păstrează ordinea celor egali
Lista este deja alfabetică. Sortarea stabilă după oraș păstrează ordinea alfabetică în interiorul fiecărui oraș.
package main
import (
"fmt"
"sort"
)
type Persoana struct {
Nume, Oras string
}
func main() {
p := []Persoana{{"Ana", "Iași"}, {"Bogdan", "Cluj"}, {"Carmen", "Iași"}, {"Dan", "Cluj"}, {"Elena", "Iași"}}
sort.SliceStable(p, func(i, j int) bool { return p[i].Oras < p[j].Oras })
fmt.Println(p)
}
Rezultat
[{Bogdan Cluj} {Dan Cluj} {Ana Iași} {Carmen Iași} {Elena Iași}]
Exemplul 3: Același lucru cu slices.SortFunc
Funcția de comparare primește elementele. cmp.Compare(b.Nota, a.Nota) (cu ordinea inversată) dă ordinea descrescătoare.
package main
import (
"cmp"
"fmt"
"slices"
)
type Elev struct {
Nume string
Nota int
}
func main() {
elevi := []Elev{{"Ana", 9}, {"Mihai", 7}, {"Ioana", 10}, {"Radu", 8}}
slices.SortFunc(elevi, func(a, b Elev) int {
return cmp.Compare(b.Nota, a.Nota)
})
fmt.Println(elevi)
}
Rezultat
[{Ioana 10} {Ana 9} {Radu 8} {Mihai 7}]
Greșeli frecvente
- În funcția
lessfolosești alt slice decât cel sortat (de exemplu o copie): indicii se referă la slice-ul primit cax. - Scrii
<=în loc de<înless: funcția trebuie să fie strictă, altfel ordinea poate fi greșită. - Te bazezi pe ordinea elementelor egale după
sort.Slice: nu este garantată. Foloseștesort.SliceStablesauslices.SortStableFunc.
Comenzi înrudite
slices.SortFunc: Sortează un slice după o funcție de comparare care returnează negativ, zero sau pozitiv; SortStableFunc păstrează ordinea celor egali.sort.Sort: Sortează orice colecție care implementează sort.Interface (Len, Less, Swap); Stable păstrează ordinea elementelor egale.sort.Ints: Sortează crescător, pe loc, un []int, []string sau []float64; IntsAreSorted verifică dacă un []int este deja sortat.cmp.Or: Returnează primul argument diferit de valoarea zero a tipului („”, 0, nil); dacă toate sunt zero, returnează zero.