Rust iterator something like chunks()

Viewed 1017

This iterator

let data = vec![0, 1, 2, 3, 4, 5];

for x in data.chunks(2) {
    println!("{:?}", x);
}

will produce

[0, 1]
[2, 3]
[4, 5]

Can I use iterator to get something like this.

[0, 1]
[1, 2]
[2, 3]
[3, 4]
[4, 5]

I know how to do that using for loop. But can iterator do this better?

2 Answers

I guess your can use Itertools.tuple_windows for this. According to the documentation it "returns an iterator over all contiguous windows producing tuples of a specific size (up to 4)" :

use itertools::Itertools;
use itertools::TupleWindows;
use std::slice::Iter;

let data = vec![0, 1, 2, 3, 4, 5];

let it: TupleWindows<Iter<'_, i32>, (&i32, &i32)> = data.iter().tuple_windows();

for elem in it {
    println!("{:?}", elem);
}

Output:

(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)

Edit: As noted in comment1 by @Masklinn and comment2 by @SebastianRedl, you can also use windows from stdlib and avoid including Itertools in your project. But note that it only works for slices (or things that coerce to slices), not general iterators (which is fine in your case).

let data = vec![0, 1, 2, 3, 4, 5];

let it = data.windows(2);

for elem in it {
    println!("{:?}", elem);
}

Output:

[0, 1]
[1, 2]
[2, 3]
[3, 4]
[4, 5]

Alternatively, without extra dependencies, you can zip the same iterator, skip one item on the second one.

fn main() {
    let data = vec![0, 1, 2, 3, 4, 5];
    let i1 = data.iter();
    let i2 = data.iter();
    for (a, b) in i1.zip(i2.skip(1)) {
        println!("{} {}", a, b);
    }
}

Playground

Related