 # How to rewrite loop that uses indexing to use iterators over a vector

I have been doing some reading and discovered that indexing in Rust is not the same as C++, in Rust there is additional bounds checking when doing my_vec to ensure the index is within bounds. I am writing some performance critical code and have a loop that I currently use

``````let num_points_in_vector = new_vec.data.len() / 3;
for i in 0..new_vec.data.len()/3 {
new_vec.data[i] = other_vec[i * 3];
new_vec.data[num_points_in_vector + i] = other_vec[i * 3 + 1];
new_vec.data[num_points_in_vector * 2 + i] = other_vec[i * 3 + 2];
}
``````

I have read that iterators about the most efficient way to loop through a vector. So how would I rewrite this loop to use iterators?

You can use `split_at_mut` to divide that `new_vec` into three parts, and `other_vec.chunks_exact(3)` for the input data, something like:

``````let num_points_in_vector = new_vec.data.len() / 3;
let (new_slice1, tail) = new_vec.split_at_mut(num_points_in_vector);
let (new_slice2, new_slice3) = tail.split_at_mut(num_points_in_vector);
other_vec.chunks_exact(3)
.zip(new_slice1)
.zip(new_slice2)
.zip(new_slice3)
.for_each(|(((chunk, x), y), z)| {
x = chunk;
y = chunk;
z = chunk;
});
``````

Itertools' `izip!` is nice for dealing with multiple zips too.

2 Likes

sorry for what is likely a dumb question, but I am quite new to Rust and it's concept of zipping. What would the izip! version look like? Thanks in advance!

IIRC, it basically just "flattens" the zip tuples, like:

``````izip!(other_vec.chunks_exact(3), new_slice1, new_slice2, new_slice3)
.for_each(|(chunk, x, y, z)| {
x = chunk;
y = chunk;
z = chunk;
});
``````

You can also stay in `for` loop with either of these iterators if you prefer:

``````for (chunk, x, y, z) in izip!(other_vec.chunks_exact(3), new_slice1, new_slice2, new_slice3) {
x = chunk;
y = chunk;
z = chunk;
}
``````

Some iterators like `chain` and `flat_map` can do better internal folding with `for_each`, but I don't think it matters for simple `zip`s.

is there any effective difference between for_each and for? Or is it basically syntactic sugar and it compiles down to the same thing? Thanks for the tips.

A `for` loop calls `Iterator::next` repeatedly, whereas `for_each` is basically a `fold` with an empty `()` accumulator. It only makes a difference if the iterator specializes `fold` to do something better than repeating `next()` in a loop.

For example, `Chain::next` has to check its state on every call to see if it's on the first or second part of the chain. But in `Chain::fold` it can just fold the first part entirely, then fold the second part entirely. Sometimes the compiler optimizer can figure this out in a `for` loop anyway, "hoisting" the condition out of the loop, but it's more reliable to do that explicitly.

1 Like

Thanks for the tips. Exactly what I need, I will mark yours as the solution.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.