Ce face Iterator::min_by_key
max_by_key(|e| cheie) returnează elementul pentru care cheia este cea mai mare: produsul cel mai scump, elevul cel mai mare, cuvântul cel mai lung. min_by_key face invers. Cheia trebuie să implementeze Ord, deci nu poate fi f64.
max_by(|a, b| ...) și min_by primesc o funcție de comparare care returnează Ordering. Sunt necesare pentru f64 (a.total_cmp(b)) sau pentru criterii compuse (a.x.cmp(&b.x).then(...)).
La egalitate, variantele max returnează ultimul element maxim, iar variantele min primul element minim. Pentru un iterator gol, rezultatul este None.
Parametri
| Parametru | Descriere |
|---|---|
f |
La *_by_key: closure care calculează cheia unui element (primit ca &). |
compare |
La *_by: closure care compară două elemente și returnează Ordering. |
Ce returnează
Option<Self::Item>: elementul întreg, nu cheia.
Exemple
Exemplul 1: Cel mai tânăr și cel mai în vârstă
fn main() {
let elevi = [("Ana", 17), ("Mihai", 15), ("Ioana", 18), ("Radu", 16)];
let tanar = elevi.iter().min_by_key(|(_, varsta)| *varsta);
let mare = elevi.iter().max_by_key(|(_, varsta)| *varsta);
println!("cel mai tânăr: {:?}", tanar);
println!("cel mai mare: {:?}", mare);
let cuvinte = ["mere", "portocale", "kiwi"];
println!("cel mai lung: {:?}", cuvinte.iter().max_by_key(|c| c.chars().count()));
}
Rezultat
cel mai tânăr: Some(("Mihai", 15))
cel mai mare: Some(("Ioana", 18))
cel mai lung: Some("portocale")
Exemplul 2: Produsul cel mai ieftin, cu prețuri f64
fn main() {
let produse: [(&str, f64); 4] = [("lapte", 8.49), ("pâine", 4.99), ("cafea", 24.5), ("ouă", 14.9)];
let ieftin = produse.iter().min_by(|a, b| a.1.total_cmp(&b.1));
let scump = produse.iter().max_by(|a, b| a.1.total_cmp(&b.1));
if let (Some(i), Some(s)) = (ieftin, scump) {
println!("cel mai ieftin: {} ({:.2} lei)", i.0, i.1);
println!("cel mai scump: {} ({:.2} lei)", s.0, s.1);
}
}
Rezultat
cel mai ieftin: pâine (4.99 lei)
cel mai scump: cafea (24.50 lei)
Exemplul 3: Egalitate: primul minim, ultimul maxim
Ana și Mihai au amândoi 95 de puncte; max_by_key îl dă pe ultimul, Mihai. Radu și Elena au 70; min_by_key o dă pe prima, Elena.
fn main() {
let puncte = [("Ana", 95), ("Elena", 70), ("Mihai", 95), ("Radu", 70)];
println!("max: {:?}", puncte.iter().max_by_key(|p| p.1));
println!("min: {:?}", puncte.iter().min_by_key(|p| p.1));
}
Rezultat
max: Some(("Mihai", 95))
min: Some(("Elena", 70))
Greșeli frecvente
- Folosești o cheie
f64înmax_by_key: the trait bound `f64: Ord` is not satisfied. Foloseștemax_by(|a, b| a.x.total_cmp(&b.x)). - Te aștepți să primești cheia (de exemplu vârsta): primești elementul întreg. Extrage câmpul după aceea.
- Contezi pe un anumit element la egalitate fără să știi regula:
max_*dă ultimul,min_*dă primul.
Comenzi înrudite
Iterator::min: Returnează cel mai mic (min) sau cel mai mare (max) element, ca Option: None pentru un iterator gol.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.Iterator::reduce: Combină elementele două câte două, folosind primul element ca valoare inițială; returnează None pentru un iterator gol.HashMap::keys: keys parcurge doar cheile, values doar valorile, iar values_mut dă valorile ca referințe mutabile, pentru modificare.