Ordering în Rust

Rezultatul unei comparații: Less, Equal sau Greater; are then, then_with și reverse pentru sortări pe mai multe criterii.

Sintaxă
pub enum Ordering {
    Less = -1,
    Equal = 0,
    Greater = 1,
}

Ce face Ordering

std::cmp::Ordering este enum-ul returnat de cmp și folosit de sort_by, max_by, binary_search_by. Îl tratezi de obicei cu match sau cu metodele is_lt(), is_eq(), is_gt(), is_le(), is_ge(), is_ne().

a.then(b) returnează a dacă nu este Equal, altfel b: așa legi mai multe criterii de sortare. then_with(|| ...) face la fel, dar calculează al doilea criteriu doar când e nevoie. reverse() inversează rezultatul (sortare descrescătoare).

Parametri

Parametru Descriere
then(other) Criteriul următor, folosit doar la egalitate.
then_with(f) Ca then, dar calculat leneș printr-un closure.
reverse() Inversează Less și Greater.

Ce returnează

Metodele returnează tot un Ordering (sau bool pentru is_*).

Exemple

Exemplul 1: Sortare după oraș, apoi după vârstă descrescător

fn main() {
    let mut persoane = vec![
        ("Ana", "Iași", 31),
        ("Mihai", "Cluj", 25),
        ("Elena", "Iași", 45),
        ("Radu", "Cluj", 52),
    ];
    persoane.sort_by(|a, b| a.1.cmp(b.1).then(b.2.cmp(&a.2)));
    for (nume, oras, varsta) in &persoane {
        println!("{oras:<5} {varsta} {nume}");
    }
}

Rezultat

Cluj  52 Radu
Cluj  25 Mihai
Iași  45 Elena
Iași  31 Ana

Exemplul 2: match, reverse și metodele is_*

use std::cmp::Ordering;

fn descrie(o: Ordering) -> &'static str {
    match o {
        Ordering::Less => "mai mic",
        Ordering::Equal => "egal",
        Ordering::Greater => "mai mare",
    }
}

fn main() {
    let o = 5.cmp(&9);
    println!("5 față de 9: {}, inversat: {}", descrie(o), descrie(o.reverse()));
    println!("is_lt: {}, is_ge: {}", o.is_lt(), o.is_ge());
    println!("ca număr: {}", o as i8);

    let mut v = vec![3, 1, 2];
    v.sort_by(|a, b| a.cmp(b).reverse());
    println!("{v:?}");
}

Rezultat

5 față de 9: mai mic, inversat: mai mare
is_lt: true, is_ge: false
ca număr: -1
[3, 2, 1]

Greșeli frecvente

  • Scrii sort_by(|a, b| a.x > b.x): sort_by așteaptă un Ordering, nu bool. Scrie a.x.cmp(&b.x).
  • Confunzi std::cmp::Ordering cu std::sync::atomic::Ordering (folosit la variabile atomice). Sunt tipuri diferite cu același nume.

Comenzi înrudite

  • Ord: Ordonare totală: orice două valori se pot compara. cmp() returnează Ordering; necesar pentru sort(), BTreeMap, max().
  • PartialOrd: Trait-ul din spatele operatorilor <, >, <=, >=; partial_cmp poate returna None (ex. NaN la f64).
  • Ord::max: Returnează cea mai mare (max) sau cea mai mică (min) dintre două valori ale unui tip Ord.