Iterator::unzip în Rust

Desparte un iterator de perechi în două colecții: una cu primele elemente, alta cu al doilea element din fiecare pereche.

Sintaxă
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where Self: Iterator<Item = (A, B)>, FromA: Default + Extend<A>, FromB: Default + Extend<B>

Ce face Iterator::unzip

unzip() este inversul lui zip: din (a1, b1), (a2, b2), ... construiește ([a1, a2, ...], [b1, b2, ...]). Tipul colecțiilor se precizează, de obicei (Vec<_>, Vec<_>).

Este util după map sau enumerate, când vrei două liste paralele (de exemplu etichete și valori pentru un grafic). Este un consumator: parcurge iteratorul (sau doar cât are nevoie) și pornește lanțul de adaptoare leneșe din fața lui.

Ce returnează

Un tuplu cu două colecții.

Exemple

Exemplul 1: Nume și note în liste separate

fn main() {
    let catalog = [("Ana", 9), ("Mihai", 7), ("Ioana", 10)];
    let (nume, note): (Vec<&str>, Vec<u32>) = catalog.iter().copied().unzip();
    println!("{:?}", nume);
    println!("{:?}", note);
}

Rezultat

["Ana", "Mihai", "Ioana"]
[9, 7, 10]

Exemplul 2: Etichete și valori pentru un grafic

fn main() {
    let vanzari = [("ian", 120.0), ("feb", 98.5), ("mar", 143.25)];
    let (luni, valori): (Vec<String>, Vec<f64>) = vanzari
        .iter()
        .map(|(l, v)| (l.to_uppercase(), v * 1.21))
        .unzip();
    println!("{:?}", luni);
    println!("{:.2?}", valori);
}

Rezultat

["IAN", "FEB", "MAR"]
[145.20, 119.19, 173.33]

Greșeli frecvente

  • Apelezi unzip pe un iterator care nu produce perechi: nu compilează. Transformă întâi cu map(|x| (a, b)).
  • Uiți tipul rezultatului: type annotations needed.

Comenzi înrudite

  • Iterator::zip: Parcurge două șiruri în paralel și produce perechi (a, b); se oprește când se termină cel mai scurt.
  • Iterator::partition: Împarte elementele în două colecții: cele pentru care condiția e adevărată și cele pentru care e falsă.
  • Iterator::collect: Consumă iteratorul și adună valorile într-o colecție: Vec, String, HashMap, HashSet, chiar Result sau Option.
  • Iterator::enumerate: Adaugă fiecărui element poziția lui: produce perechi (index, element), cu indexul pornind de la 0.