slices.SortFunc în Go

Sortează un slice după o funcție de comparare care returnează negativ, zero sau pozitiv; SortStableFunc păstrează ordinea celor egali.

Sintaxă
import "slices"

func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int)
func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int)

Ce face slices.SortFunc

slices.SortFunc(x, cmp) sortează pe loc un slice de orice tip, de exemplu structuri. Funcția cmp(a, b) primește două elemente și returnează un număr negativ dacă a vine înaintea lui b, zero dacă sunt egale și pozitiv dacă a vine după b.

Cel mai simplu scrii funcția cu cmp.Compare(a.Camp, b.Camp) pentru numere și texte, sau strings.Compare. Pentru ordine descrescătoare inversezi argumentele. Pentru mai multe criterii (întâi orașul, apoi numele) combini comparațiile cu cmp.Or.

SortFunc nu este stabilă. slices.SortStableFunc păstrează ordinea inițială a elementelor pentru care cmp returnează 0.

Parametri

Parametru Descriere
x Slice-ul de sortat.
cmp Funcția de comparare: negativ, 0 sau pozitiv.

Ce returnează

Nimic; slice-ul este sortat pe loc.

Exemple

Exemplul 1: Produse după preț, apoi după nume

package main

import (
    "cmp"
    "fmt"
    "slices"
)

type Produs struct {
    Nume string
    Pret float64
}

func main() {
    cos := []Produs{{"lapte", 7.5}, {"pâine", 4.2}, {"brânză", 25}, {"apă", 4.2}}
    slices.SortFunc(cos, func(a, b Produs) int {
        return cmp.Or(
            cmp.Compare(a.Pret, b.Pret),
            cmp.Compare(a.Nume, b.Nume),
        )
    })
    for _, p := range cos {
        fmt.Printf("%-7s %5.2f lei\n", p.Nume, p.Pret)
    }
}

Rezultat

apă      4.20 lei
pâine    4.20 lei
lapte    7.50 lei
brânză  25.00 lei

Exemplul 2: Descrescător și sortare stabilă

Elevii sunt înscriși în ordinea sosirii. Sortarea stabilă după notă (descrescător) păstrează ordinea sosirii între cei cu aceeași notă.

package main

import (
    "cmp"
    "fmt"
    "slices"
)

type Elev struct {
    Nume string
    Nota int
}

func main() {
    elevi := []Elev{{"Radu", 9}, {"Ana", 10}, {"Mihai", 9}, {"Ioana", 10}, {"Dan", 8}}
    slices.SortStableFunc(elevi, func(a, b Elev) int {
        return cmp.Compare(b.Nota, a.Nota)
    })
    fmt.Println(elevi)
}

Rezultat

[{Ana 10} {Ioana 10} {Radu 9} {Mihai 9} {Dan 8}]

Exemplul 3: Texte fără să ții cont de litere mari sau mici

package main

import (
    "fmt"
    "slices"
    "strings"
)

func main() {
    orase := []string{"iași", "Cluj", "arad", "Brașov"}
    slices.SortFunc(orase, func(a, b string) int {
        return strings.Compare(strings.ToLower(a), strings.ToLower(b))
    })
    fmt.Println(orase)
}

Rezultat

[arad Brașov Cluj iași]

Greșeli frecvente

  • Scrii funcția de comparare ca return a.Pret - b.Pret: pentru float64 nu compilează (trebuie int), iar pentru întregi mari scăderea poate depăși limita. Folosește cmp.Compare.
  • Returnezi doar -1 sau 1 și uiți de egalitate (0): sortarea stabilă nu mai poate păstra ordinea celor egali.

Comenzi înrudite

  • slices.Sort: Sortează crescător, pe loc, un slice de orice tip ordonat (numere, texte).
  • cmp.Compare: Compare returnează -1, 0 sau +1 după cum x este mai mic, egal sau mai mare decât y; Less spune dacă x < y.
  • cmp.Or: Returnează primul argument diferit de valoarea zero a tipului („”, 0, nil); dacă toate sunt zero, returnează zero.
  • sort.Slice: Sortează un slice de orice tip după o funcție less(i, j); SliceStable păstrează ordinea elementelor egale.
  • slices.Sorted: Strânge valorile unui iterator într-un slice nou și îl sortează: Sorted (ordine naturală), SortedFunc și SortedStableFunc (comparație proprie).