HashMap::retain în Rust

Păstrează doar perechile pentru care funcția dată returnează true; restul sunt șterse dintr-o singură trecere.

Sintaxă
pub fn retain<F>(&mut self, f: F)
where F: FnMut(&K, &mut V) -> bool

Ce face HashMap::retain

retain(|cheie, valoare| condiție) trece prin toate perechile și le șterge pe cele pentru care closure-ul returnează false. Este modul corect de a șterge mai multe chei după o condiție, pentru că nu poți apela remove în timp ce parcurgi dicționarul.

Closure-ul primește valoarea ca &mut V, deci poate și s-o modifice înainte de a decide (de exemplu, scade un termen și șterge perechile expirate).

Parametri

Parametru Descriere
f Closure-ul care primește (&K, &mut V) și returnează true pentru perechile păstrate.

Ce returnează

Nimic; dicționarul este modificat.

Exemple

Exemplul 1: Fără produse epuizate

use std::collections::HashMap;

fn main() {
    let mut stoc = HashMap::from([("mere", 12), ("pere", 0), ("prune", 5), ("caise", 0)]);
    stoc.retain(|_, cantitate| *cantitate > 0);
    let mut ramase: Vec<_> = stoc.into_iter().collect();
    ramase.sort();
    println!("{:?}", ramase);
}

Rezultat

[("mere", 12), ("prune", 5)]

Exemplul 2: Sesiuni care expiră

La fiecare minut, fiecare sesiune pierde un minut; cele ajunse la 0 sunt șterse în aceeași trecere.

use std::collections::HashMap;

fn main() {
    let mut sesiuni = HashMap::from([("ana", 3), ("mihai", 1), ("ioana", 2)]);
    for minut in 1..=3 {
        sesiuni.retain(|_, ramas| {
            *ramas -= 1;
            *ramas > 0
        });
        let mut active: Vec<_> = sesiuni.keys().copied().collect();
        active.sort();
        println!("după minutul {minut}: {:?}", active);
    }
}

Rezultat

după minutul 1: ["ana", "ioana"]
după minutul 2: ["ana"]
după minutul 3: []

Greșeli frecvente

  • Inversezi condiția: closure-ul spune ce rămâne, nu ce se șterge.
  • Încerci for k in m.keys() { if .. { m.remove(k); } }: nu compilează. retain face exact asta.

Comenzi înrudite

  • Vec::retain: Păstrează în vector doar elementele pentru care funcția dată returnează true; restul sunt șterse, în aceeași ordine.
  • HashMap::remove: Scoate o cheie din dicționar și returnează valoarea ei în Some; None dacă cheia nu exista.
  • HashMap::drain: Golește dicționarul și dă toate perechile ca iterator, prin valoare; dicționarul rămâne gol, dar utilizabil.
  • HashMap::iter: Parcurge perechile din dicționar: iter dă (&cheie, &valoare), iter_mut dă (&cheie, &mut valoare). Ordinea e aleatorie.