Vec::windows în Rust

windows dă ferestre suprapuse de câte n elemente consecutive; chunks împarte vectorul în bucăți separate de câte n.

Sintaxă
pub fn windows(&self, size: usize) -> Windows<'_, T>
pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Ce face Vec::windows

windows(n) produce toate secvențele de n elemente alăturate, alunecând cu câte o poziție: pentru [1, 2, 3, 4] și n = 2 obții [1, 2], [2, 3], [3, 4]. Este ideal pentru diferențe între valori consecutive, medii mobile sau verificări de tip „fiecare element e mai mare decât cel dinainte”.

chunks(n) împarte vectorul în bucăți de câte n elemente fără suprapunere; ultima bucată poate fi mai mică. Este util pentru loturi, pagini sau echipe. chunks_exact(n) dă doar bucățile complete.

Ambele returnează iteratori de slice-uri (&[T]), deci nu copiază nimic. Dacă vectorul are mai puțin de n elemente, windows nu produce nimic. n = 0 oprește programul cu panic.

Parametri

Parametru Descriere
size / chunk_size Numărul de elemente din fiecare fereastră sau bucată (mai mare decât 0).

Ce returnează

Un iterator care produce slice-uri &[T].

Exemple

Exemplul 1: Diferențe de temperatură și media pe 3 zile

{dif:+} afișează semnul și pentru numerele pozitive. {:.2?} aplică două zecimale fiecărui element din vector.

fn main() {
    let temperaturi = vec![12, 15, 11, 18, 20, 17];
    for fereastra in temperaturi.windows(2) {
        let dif = fereastra[1] - fereastra[0];
        println!("{:?}: diferență {dif:+}", fereastra);
    }
    let medii: Vec<f64> = temperaturi
        .windows(3)
        .map(|w| w.iter().sum::<i32>() as f64 / 3.0)
        .collect();
    println!("medii pe 3 zile: {:.2?}", medii);
}

Rezultat

[12, 15]: diferență +3
[15, 11]: diferență -4
[11, 18]: diferență +7
[18, 20]: diferență +2
[20, 17]: diferență -3
medii pe 3 zile: [12.67, 14.67, 16.33, 18.33]

Exemplul 2: Echipe de câte 3

fn main() {
    let elevi = vec!["Ana", "Bogdan", "Cristina", "Dan", "Elena", "Florin", "Gabi"];
    for (i, echipa) in elevi.chunks(3).enumerate() {
        println!("echipa {}: {:?}", i + 1, echipa);
    }
    println!("{} ferestre de 3, {} bucăți de 3", elevi.windows(3).count(), elevi.chunks(3).count());
}

Rezultat

echipa 1: ["Ana", "Bogdan", "Cristina"]
echipa 2: ["Dan", "Elena", "Florin"]
echipa 3: ["Gabi"]
5 ferestre de 3, 3 bucăți de 3

Exemplul 3: Șir crescător? Valori repetate?

fn main() {
    let note = vec![5, 7, 7, 9, 10];
    let crescator = note.windows(2).all(|w| w[0] <= w[1]);
    let repetari = note.windows(2).filter(|w| w[0] == w[1]).count();
    println!("crescător: {crescator}, perechi egale alăturate: {repetari}");
}

Rezultat

crescător: true, perechi egale alăturate: 1

Greșeli frecvente

  • Confunzi cele două: windows se suprapune (alunecă cu o poziție), chunks nu.
  • Accesezi w[2] într-o fereastră de 2: panic. Fiecare fereastră are exact n elemente; o bucată din chunks poate avea mai puține.
  • Apelezi windows(0) sau chunks(0), de exemplu cu o mărime calculată: programul se oprește.

Comenzi înrudite

  • Vec::split_at: Împarte vectorul în două slice-uri la o poziție, fără copiere: elementele dinainte și elementele de la poziție încolo.
  • Vec::iter: Cele trei moduri de a parcurge un vector: iter dă referințe, iter_mut dă referințe mutabile, into_iter dă elementele.
  • Iterator::step_by: Produce primul element și apoi fiecare al n-lea: sare peste elemente cu un pas fix.
  • Iterator::zip: Parcurge două șiruri în paralel și produce perechi (a, b); se oprește când se termină cel mai scurt.