Ce face Iterator::flat_map
flatten() primește un iterator ale cărui elemente sunt la rândul lor parcurgibile (vectori, slice-uri, Option-uri, iteratori) și produce elementele interioare, pe rând: din [[1, 2], [3]] obții 1, 2, 3. Pentru Option, None nu produce nimic, iar Some(x) produce x.
flat_map(f) este map(f).flatten(): pentru fiecare element, f returnează o colecție sau un iterator, iar rezultatele se lipesc într-un singur șir. Exemplu tipic: din linii de text, toate cuvintele (lines().flat_map(|l| l.split_whitespace())). Ca toate adaptoarele, este leneș: nu face nimic până când iteratorul nu este consumat (de for, collect, sum, count etc.).
Parametri
| Parametru | Descriere |
|---|---|
f |
La flat_map: closure-ul care returnează, pentru fiecare element, ceva parcurgibil. |
Ce returnează
Un iterator cu elementele interioare, în ordine.
Exemple
Exemplul 1: Toate cuvintele din mai multe linii
fn main() {
let text = "Ana are mere\nMihai are pere\nIoana nu are nimic";
let cuvinte: Vec<&str> = text.lines().flat_map(|l| l.split_whitespace()).collect();
println!("{} cuvinte: {:?}", cuvinte.len(), cuvinte);
}
Rezultat
10 cuvinte: ["Ana", "are", "mere", "Mihai", "are", "pere", "Ioana", "nu", "are", "nimic"]
Exemplul 2: flatten pe vectori și pe Option
fn main() {
let grupe = vec![vec!["Ana", "Mihai"], vec![], vec!["Ioana", "Radu", "Elena"]];
let toti: Vec<&str> = grupe.into_iter().flatten().collect();
println!("{:?}", toti);
let raspunsuri = [Some(8), None, Some(10), None, Some(6)];
let date: Vec<i32> = raspunsuri.into_iter().flatten().collect();
println!("{:?}", date);
}
Rezultat
["Ana", "Mihai", "Ioana", "Radu", "Elena"]
[8, 10, 6]
Exemplul 3: Toate combinațiile meniului
Pentru fiecare fel principal, flat_map produce câte o combinație cu fiecare desert.
fn main() {
let feluri = ["sarmale", "ciorbă"];
let deserturi = ["papanași", "clătite", "cozonac"];
let meniuri: Vec<String> = feluri
.iter()
.flat_map(|f| deserturi.iter().map(move |d| format!("{f} + {d}")))
.collect();
for m in &meniuri {
println!("{m}");
}
}
Rezultat
sarmale + papanași
sarmale + clătite
sarmale + cozonac
ciorbă + papanași
ciorbă + clătite
ciorbă + cozonac
Greșeli frecvente
- Folosești
mapcând funcția returnează un vector și obțiiVec<Vec<T>>. Dacă vrei o singură listă, foloseșteflat_map. - În closure-ul interior folosești o variabilă din cel exterior fără
move: closure may outlive the current function, but it borrows `f`. Adaugămovela closure-ul interior.
Comenzi înrudite
Iterator::map: Transformă fiecare valoare a iteratorului cu o funcție și dă un iterator cu rezultatele; nu calculează nimic până la consumare.Iterator::chain: Lipește două șiruri de valori: produce întâi toate elementele primului, apoi pe ale celui de-al doilea.Vec::concat: concat lipește o listă de liste (sau de texte) într-una singură; join face la fel, cu un separator între ele.Iterator::filter_map: Transformă și filtrează într-un singur pas: păstrează valorile din Some(..) returnate de funcție și sare peste None.