mazznoer
mazznoer

Reputation: 113

Rust iterator something like chunks()

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?

Upvotes: 6

Views: 4537

Answers (2)

mgc
mgc

Reputation: 5443

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]

Upvotes: 7

Netwave
Netwave

Reputation: 42796

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

Upvotes: 7

Related Questions