# Why does a doubly-reversed iterator act as if it was never reversed?

• A+
Category：Languages

I have an input vector which contains numbers. In an output vector, I need to get a sequence of partial products but in right-to-left order. The last element of the output must be equal to the last one in the input; the second-to-last element of the output must be a product of the last and second-to-last elements of input; and so on. For example, if the input vector is

``let input = vec![2, 3, 4]; ``

then I need the output to be `[24, 12, 4]`.

My implementation takes an iterator over the input, reverses it, `map`s, reverses again and `collect`s:

``fn main() {     let input = vec![2, 3, 4];     let mut prod = 1;     let p: Vec<usize> = input         .iter()         .rev()         .map(|v| {             prod *= v;             prod         }).rev()         .collect();     println!("{:?}", p); } ``

The result is `[2, 6, 24]`, the same as if I delete both `rev()`s. The two `rev()`s do not solve the problem, they just "annihilate" each other.

Is this task solvable in "chain of calls" style, without using `for`?

This behavior is actually explicitly described in the documentation:

# Notes about side effects

The `map` iterator implements `DoubleEndedIterator`, meaning that you can also `map` backwards:

[…]

But if your closure has state, iterating backwards may act in a way you do not expect. […]

A way to solve this would be by adding an intermediary `collect` to be sure that the second `rev` does not apply on the `Map`:

``fn main() {     let input = vec![2, 3, 4];     let mut prod = 1;     let p: Vec<usize> = input         .iter()         .map(|v| {             prod *= v;             prod         }).rev()         .collect::<Vec<_>>()         .into_iter()         .rev()         .collect();     println!("{:?}", p); } ``

But that requires an extra allocation. Another way would be to collect, and then reverse:

``fn main() {     let input = vec![2, 3, 4];     let mut prod = 1;     let mut p: Vec<usize> = input         .iter()         .rev()         .map(|v| {             prod *= v;             prod         }).collect();     p.reverse();      println!("{:?}", p); } ``