6

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?

mazznoer
  • 103
  • 2
  • 9
  • 1
    Does this answer your question? [Are there equivalents to slice::chunks/windows for iterators to loop over pairs, triplets etc?](https://stackoverflow.com/questions/42134874/are-there-equivalents-to-slicechunks-windows-for-iterators-to-loop-over-pairs) – hellow Jan 21 '21 at 08:20

2 Answers2

6

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]
mgc
  • 5,223
  • 1
  • 24
  • 37
  • 4
    FWIW there's [`windows`](https://doc.rust-lang.org/std/primitive.slice.html#method.windows) in the stdlib which iterates on slices and would probably be sufficient here. – Masklinn Jan 21 '21 at 08:56
  • @Masklinn thanks, I edited my answer to include your suggestion. – mgc Jan 21 '21 at 09:30
  • 2
    @mgc You should note in your answer that `windows` works only for slices (or things that coerce to them), not general iterators. – Sebastian Redl Jan 21 '21 at 09:34
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

Netwave
  • 40,134
  • 6
  • 50
  • 93