BTreeMap::range în Rust

Parcurge doar perechile cu cheile într-un interval (a..b, a..=b, a.., ..b), în ordine crescătoare.

Sintaxă
pub fn range<T: ?Sized, R>(&self, range: R) -> Range<'_, K, V>
where K: Borrow<T> + Ord, T: Ord, R: RangeBounds<T>

Ce face BTreeMap::range

range(a..b) returnează un iterator peste perechile (&K, &V) cu cheile între a (inclusiv) și b (exclusiv). Merg toate formele de interval: a..=b, a.., ..b. Căutarea începutului este rapidă (logaritmică), deci nu se parcurge tot dicționarul.

Iteratorul poate fi parcurs și de la coadă: range(..x).next_back() dă cea mai mare cheie mai mică decât x („ultimul eveniment înainte de…”). range_mut dă valorile ca &mut V.

Un interval invers (5..2) oprește programul cu panic.

Parametri

Parametru Descriere
range Intervalul de chei: a..b, a..=b, a.., ..b, ...

Ce returnează

Un iterator de perechi (&K, &V), în ordinea cheilor.

Exemple

Exemplul 1: Evenimente pe perioade

use std::collections::BTreeMap;

fn main() {
    let evenimente = BTreeMap::from([
        (1859, "Unirea Principatelor"),
        (1877, "Independența"),
        (1918, "Marea Unire"),
        (1989, "Revoluția"),
        (2004, "aderarea la NATO"),
        (2007, "aderarea la UE"),
    ]);
    println!("Secolul XX:");
    for (an, ce) in evenimente.range(1901..=2000) {
        println!("  {an}: {ce}");
    }
    println!("după 2000: {:?}", evenimente.range(2001..).collect::<Vec<_>>());
    println!("ultimul înainte de 1950: {:?}", evenimente.range(..1950).next_back());
}

Rezultat

Secolul XX:
  1918: Marea Unire
  1989: Revoluția
după 2000: [(2004, "aderarea la NATO"), (2007, "aderarea la UE")]
ultimul înainte de 1950: Some((1918, "Marea Unire"))

Exemplul 2: Cuvinte care încep cu „ma”

Toate cuvintele cu prefixul „ma” sunt între „ma” (inclusiv) și „mb” (exclusiv).

use std::collections::BTreeMap;

fn main() {
    let dictionar = BTreeMap::from([
        ("mama", "mamă"),
        ("mare", "întindere de apă sărată"),
        ("masă", "mobilă cu blat"),
        ("mere", "fructe"),
        ("lac", "apă stătătoare"),
        ("mașină", "vehicul"),
    ]);
    for (cuvant, sens) in dictionar.range("ma".."mb") {
        println!("{cuvant}: {sens}");
    }
}

Rezultat

mama: mamă
mare: întindere de apă sărată
masă: mobilă cu blat
mașină: vehicul

Exemplul 3: Corectarea citirilor dintr-un interval orar

Senzorul a raportat greșit între 12 și 14; range_mut corectează doar acele valori.

use std::collections::BTreeMap;

fn main() {
    let mut temperaturi: BTreeMap<u32, i32> = (8..=16).map(|ora| (ora, 20)).collect();
    for (_, t) in temperaturi.range_mut(12..=14) {
        *t += 5;
    }
    for (ora, t) in &temperaturi {
        println!("{ora:02}:00  {t}°C");
    }
}

Rezultat

08:00  20°C
09:00  20°C
10:00  20°C
11:00  20°C
12:00  25°C
13:00  25°C
14:00  25°C
15:00  20°C
16:00  20°C

Greșeli frecvente

  • Dai un interval invers (range(2000..1900)): programul se oprește cu panic.
  • Pentru chei String scrii m.range("a".."c"): the trait bound `String: Borrow<&str>` is not satisfied. Scrie capetele cu std::ops::Bound: m.range::<str, _>((Bound::Included("a"), Bound::Excluded("c"))).
  • Folosești iter().filter(|(k, _)| ..) pentru un interval de chei: parcurge tot dicționarul. range sare direct la început.

Comenzi înrudite

  • BTreeMap: Dicționar cu cheile mereu sortate: aceleași operații ca HashMap, dar parcurgerea și afișarea sunt în ordinea cheilor.
  • BTreeSet::range: Parcurge doar elementele dintr-un interval de valori, în ordine; util pentru „următorul după x” sau „toate dintre a și b”.
  • BTreeMap::first_key_value: Returnează perechea cu cea mai mică cheie (first) sau cu cea mai mare cheie (last); None dacă dicționarul e gol.
  • Range: Intervalul a..b: toate valorile de la a inclusiv până la b exclusiv. Este iterator, se folosește în for și la tăierea slice-urilor.