Vec::sort în Rust

Sortează vectorul crescător, pe loc. sort este stabilă (păstrează ordinea elementelor egale); sort_unstable e mai rapidă.

Sintaxă
pub fn sort(&mut self)            // T: Ord, stabilă
pub fn sort_unstable(&mut self)   // T: Ord, Rust 1.20

Ce face Vec::sort

sort() ordonează elementele crescător, folosind comparația naturală a tipului (trait-ul Ord): numerele după valoare, textele după ordinea octeților UTF-8, tuplurile pe rând, câmp cu câmp. Vectorul este modificat pe loc; nu se returnează nimic.

sort este stabilă: elementele egale își păstrează ordinea relativă. sort_unstable nu garantează asta, dar este de obicei mai rapidă și nu alocă memorie suplimentară. Pentru numere sau texte simple, unde elementele egale sunt identice, folosește liniștit sort_unstable.

Numerele cu virgulă (f64) nu implementează Ord, din cauza valorii NaN, deci sort() nu compilează pentru ele. Folosește sort_by(f64::total_cmp). Textele sunt comparate după octeți, nu după alfabetul românesc: „Ștei” ajunge după „Zalău”, iar literele mari vin înaintea celor mici.

Ce returnează

Nimic; vectorul este sortat pe loc.

Exemple

Exemplul 1: Numere și orașe

„Ștei” ajunge ultimul: „Ș” are un cod Unicode mai mare decât toate literele fără diacritice.

fn main() {
    let mut note = vec![7, 10, 4, 9, 8];
    note.sort();
    println!("{:?}", note);

    let mut orase = vec!["Iași", "Ștei", "Arad", "Cluj", "Brașov", "Zalău"];
    orase.sort_unstable();
    println!("{:?}", orase);
}

Rezultat

[4, 7, 8, 9, 10]
["Arad", "Brașov", "Cluj", "Iași", "Zalău", "Ștei"]

Exemplul 2: Numere cu virgulă: sort_by(f64::total_cmp)

temperaturi.sort() ar da eroarea the trait bound `f64: Ord` is not satisfied. total_cmp definește o ordine completă pentru f64.

fn main() {
    let mut temperaturi = vec![12.5, -3.0, 7.25, 0.0, 21.0];
    temperaturi.sort_by(f64::total_cmp);
    println!("{:?}", temperaturi);
}

Rezultat

[-3.0, 0.0, 7.25, 12.5, 21.0]

Exemplul 3: Tupluri: după nume, apoi după prenume

Tuplurile se compară pe rând: întâi primul câmp, iar la egalitate al doilea.

fn main() {
    let mut elevi = vec![("Popescu", "Ana"), ("Ionescu", "Mihai"), ("Popescu", "Andrei"), ("Ionescu", "Elena")];
    elevi.sort();
    for (nume, prenume) in &elevi {
        println!("{nume} {prenume}");
    }
}

Rezultat

Ionescu Elena
Ionescu Mihai
Popescu Ana
Popescu Andrei

Greșeli frecvente

  • Scrii let sortat = v.sort();. sort returnează (), nu vectorul sortat; sortează v pe loc și folosește apoi v.
  • Sortezi un Vec<f64> cu sort(): nu compilează. Folosește sort_by(f64::total_cmp) sau sort_by(|a, b| a.total_cmp(b)).
  • Te aștepți la ordine alfabetică românească. Sortarea compară octeți: „ana” vine după „Zalău”, iar „Ș” după „Z”. Pentru ignorarea literelor mari, sortează după to_lowercase().

Comenzi înrudite

  • Vec::sort_by: Sortează după o regulă proprie: sort_by primește o funcție de comparare, sort_by_key o cheie calculată din element.
  • Vec::reverse: Inversează pe loc ordinea elementelor: primul devine ultimul, ultimul devine primul.
  • Vec::binary_search: Caută rapid o valoare într-un vector sortat: Ok(poziție) dacă există, Err(poziție) unde ar trebui inserată.
  • Vec::dedup: Șterge elementele egale aflate unul după altul; dedup_by_key compară după o cheie calculată din fiecare element.
  • Reverse: Învelitoare care inversează ordinea unei valori: transformă BinaryHeap în min-heap și sortează descrescător după cheie.