Vai al contenuto
eLearner.app
Modulo 4 · Lezione 5 di 520/50 nel corso~10 min
Lezioni del modulo (5/5)

Ordinamento con il pacchetto sort

Il pacchetto standard sort ordina slice in-place. Per i tipi base (int, float64, string) ci sono helper diretti; per qualsiasi altra slice si usa sort.Slice con una funzione less(i, j int) bool che definisce l'ordinamento.

Helper per tipi base

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]

L'ordinamento è in-place: la slice originale viene mutata.

sort.Slice: ordinamento custom

Passi la slice e una funzione less che, dati due indici i e j, ritorna true se l'elemento i deve venire prima di 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)

Per ordinare in senso inverso, basta scambiare il confronto: return people[i].Age > people[j].Age.

Ordinamento stabile

sort.Slice non è garantito stabile (elementi "uguali" possono cambiare ordine relativo). Per ordinamento stabile usa sort.SliceStable:

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

Ordinamento per più chiavi

Pattern comune: ordina per età, e a parità di età per nome:

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

Ricerca binaria

sort.SearchInts / sort.Search lavorano su slice già ordinate:

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

Se l'elemento non c'è, ritorna l'indice di inserimento. Lo trovi nei dettagli quando ti serve.

Generics (Go 1.21+): slices.Sort

Dal pacchetto slices della stdlib (Go 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
})

API più moderna e type-safe. Compatibile con sort.Slice ma più ergonomica.

Prova tu

Esercizio#go.m4.l5.e1
Tentativi: 0Caricamento…

Ordina nums in modo crescente usando sort.Ints.

Caricamento editor…
Mostra suggerimento

`sort.Ints` ordina in-place uno slice di int.

Soluzione disponibile dopo 3 tentativi

Esercizio#go.m4.l5.e2
Tentativi: 0Caricamento…

Ordina people per Age crescente usando sort.Slice.

Caricamento editor…
Mostra suggerimento

La funzione less ritorna true quando l'elemento i deve venire PRIMA di j.

Soluzione disponibile dopo 3 tentativi

Quiz#go.m4.l5.e3
Pronto

Come si ordina in senso decrescente con sort.Slice?

Go
sort.Slice(s, func(i, j int) bool { return ??? })
Opzioni di risposta

Recap

  • sort.Ints / sort.Strings / sort.Float64s per tipi base, in-place.
  • sort.Slice(s, less) per slice di qualsiasi tipo, con funzione less(i, j).
  • sort.SliceStable per mantenere l'ordine relativo a parità di chiave.
  • Ordinamento per più chiavi: cascata di if nella less.
  • Go 1.21+: pacchetto slices con API generica (slices.Sort, slices.SortFunc).
  • Per chiavi di map: estrai in slice e ordina.