Suppose we have a vector:
let a = vec![1, 2, 3];
What is the best and shortest way to iterate over the elements so, that in the first iteration I receive a tuple of (1, 2)
, and in the next iteration - (2, 3)
, until there are no elements, so without producing the (3, None)
or anything like that? It seems that a.chunks(2)
is a bit different, it steps by two, while I need to step by one over every two consecutive elements in a collection.
There are multiple ways to do so:
Using the standard library:
.zip
let result = a.iter()
.zip(a.iter().skip(1))
.inspect(|(a, b)| println!("a: {}, b: {}", a, b))
.collect::<Vec<_>>();
.windows
let result = a.windows(2)
.inspect(|w| println!("a: {}, b: {}", w[0], w[1]))
.collect::<Vec<_>>();
Worth noting, in case this matters, is that windows()
iterates over subslices, so unlike the above method, collect()
in this case will not give you a Vec
of tuples.
Using the Itertools
crate:
.tuple_windows
use itertools::Itertools;
let result = a.iter()
.tuple_windows()
.inspect(|(a, b)| println!("a: {}, b: {}", a, b))
.collect::<Vec<_>>();
All of the above methods will print the following:
a: 1, b: 2
a: 2, b: 3
As a bonus, Itertools
as of recent also has a .circular_tuple_windows()
, which performs an extra iteration by including the last (3
) and first (1
) element:
use itertools::Itertools;
let result = a.iter()
.circular_tuple_windows()
.inspect(|(a, b)| println!("a: {}, b: {}", a, b))
.collect::<Vec<_>>();
a: 1, b: 2
a: 2, b: 3
a: 3, b: 1
You can also use chunks(). Now the elements will not overlap.
fn main() {
let vec = vec![1, 2, 4, 5, 8, 9];
let new_thing = vec.chunks(2).map(|x| println!("{} and {}", x[0],
x[1])).collect::<Vec<_>>();
}
1 and 2
4 and 5
8 and 9
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With