I have let my_vec = (0..25).collect::<Vec<_>>()
and I would like to split my_vec
into iterators of groups of 10:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
[20, 21, 22, 23, 24, None, None, None, None, None];
Is it possible to do that with iterators in Rust?
There is no such helper method on the Iterator
trait directly. However, there are two main ways to do it:
Use the [T]::chunks()
method (which can be called on a Vec<T>
directly). However, it has a minor difference: it won't produce None
, but the last iteration yields a smaller slice.
Example:
let my_vec = (0..25).collect::<Vec<_>>();
for chunk in my_vec.chunks(10) {
println!("{:02?}", chunk);
}
Result:
[00, 01, 02, 03, 04, 05, 06, 07, 08, 09]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[20, 21, 22, 23, 24]
Use the Itertools::chunks()
method from the crate itertools
. This crate extends the Iterator
trait from the standard library so this chunks()
method works with all iterators! Note that the usage is slightly more complicated in order to be that general. This has the same behavior as the method described above: in the last iteration, the chunk will be smaller instead of containing None
s.
Example:
extern crate itertools;
use itertools::Itertools;
for chunk in &(0..25).chunks(10) {
println!("{:02?}", chunk.collect::<Vec<_>>());
}
Result:
[00, 01, 02, 03, 04, 05, 06, 07, 08, 09]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[20, 21, 22, 23, 24]
You can achieve a similar solution as Lukas Kalbertodt's itertools example using only the standard library:
let my_vec = (0..25).collect::<Vec<_>>();
let mut my_values = my_vec.into_iter().peekable();
while my_values.peek().is_some() {
let chunk: Vec<_> = my_values.by_ref().take(10).collect();
println!("{:?}", chunk);
}
Result:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[20, 21, 22, 23, 24]
If you don't actually need the Vec
of each chunk, you can omit the collect
call and operate directly on the iterator created by by_ref
.
See also:
- What is the canonical way to implement is_empty for Iterator?
- Are there equivalents to slice::chunks/windows for iterators to loop over pairs, triplets etc?
- Why does Iterator::take_while take ownership of the iterator?
- Using the same iterator multiple times in Rust