Return the moving window of elements obtained from the Vec <u8> iterator

I am trying to figure out how to return a window of elements from a vector that I first filtered without copying it to a new vector.

So, this is a naive approach that works fine, but I think it ultimately extracts a new vector from line 5, which I really don't want to do.

let mut buf  = Vec::new();
file.read_to_end(&mut buf);
// Do some filtering of the read file and create a new vector for subsequent processing
let iter = buf.iter().filter(|&x| *x != 10 && *x != 13);
let clean_buf = Vec::from_iter(iter);
for iter in clean_buf.windows(13) {
    print!("{}",iter.len());
}

Alternative approach, where could I use chaining ()? to achieve the same without copying to the new Vec

for iter in buf.iter().filter(|&x| *x != 10 && *x != 13) {
    let window =  ???       
}
+4
source share
2 answers

You can use Vec::retaininstead filterfor this, which allows you to save Vec:

fn main() {
    let mut buf = vec![
        8, 9, 10, 11, 12, 13, 14,
        8, 9, 10, 11, 12, 13, 14,
        8, 9, 10, 11, 12, 13, 14,
    ];
    println!("{:?}", buf);
    buf.retain(|&x| x != 10 && x != 13);
    println!("{:?}", buf);
    for iter in buf.windows(13) {
        print!("{}, ", iter.len());
    }
    println!("");
}
+4
source

I do not understand how this will be possible. You speak:

,

filter , - Iterator. Iterator .

, . , , , Iterator::windows. ( ) ( ), .

, , , zip :

fn main() {
    let nums: Vec<u8> = (1..100).collect();

    fn is_even(x: &&u8) -> bool { **x % 2 == 0 }

    let a = nums.iter().filter(is_even);
    let b = nums.iter().filter(is_even).skip(1);
    let c = nums.iter().filter(is_even).skip(2);

    for z in a.zip(b).zip(c).map(|((a, b), c)| (a,b,c)) {
        println!("{:?}", z);
    }  
}

( itertools, ).

, , collect Vec, .

+1

All Articles