为什么双反转迭代器表现得好像它从未反转过一样? [英] Why does a doubly-reversed iterator act as if it was never reversed?
问题描述
我有一个包含数字的输入向量.在输出向量中,我需要获得一系列部分乘积,但按从右到左的顺序.输出的最后一个元素必须等于输入的最后一个元素;输出的倒数第二个元素必须是输入的最后一个和倒数第二个元素的乘积;等等.例如,如果输入向量是
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];
然后我需要输出为 [24, 12, 4]
.
我的实现对输入采用迭代器,将其反转,map
s,再次反转,然后 collect
s:
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);
}
结果是[2, 6, 24]
,就像我删除两个 rev()
一样.两个rev()
并没有解决问题,他们只是消灭"了对方.
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.
此任务是否可以在调用链"样式中解决,而无需使用 for
?
Is this task solvable in "chain of calls" style, without using for
?
推荐答案
这种行为实际上是 在文档中明确描述:
map
迭代器实现了 DoubleEndedIterator
, 意思是你也可以map
向后:
[…]
但是如果你的闭包有状态,向后迭代可能会像你一样没想到.[…]
But if your closure has state, iterating backwards may act in a way you do not expect. […]
解决这个问题的方法 将通过添加中介 collect
以确保第二个 rev
不适用于 Map
:
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);
}
这篇关于为什么双反转迭代器表现得好像它从未反转过一样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!