我正在尝试编写一个迭代器,它有条件地使用单独迭代器中的元素。在我的示例中,单独的迭代器应该递增sum
变量。一旦满足另一个条件*n == 4
,迭代器应该停止检查该条件,并假设其余元素是sum
变量的增量。我有以下工作示例:
fn conditional(n: &i64) -> bool {
// a lot of code here which is omitted for brevity
n % 2 == 0
}
fn main() {
let buf = vec![1,2,3,4,5,6];
let mut sum = 0;
let mut iter = buf.iter();
while let Some(n) = iter.next() {
if conditional(n) {
sum += n;
}
if *n == 4 {
// end of file - assume rest of elements are `conditional`
break;
}
};
// rest of elements [5,6]
for n in iter {
sum += n;
}
println!("sum (2+4+5+6): {:?}", sum);
}
输出:
sum (2+4+5+6): 17
游乐场连接
我宁愿用一个迭代器来写同样的东西,比如flat_map
:
fn conditional(n: &i64) -> bool {
// a lot of code here which is omitted for brevity
n % 2 == 0
}
fn main() {
let buf = vec![1,2,3,4,5,6];
let mut sum = 0;
let mut terminate = false;
buf.iter().flat_map(|n| {
if *n == 4 {
// hard terminate here - return Some(n) for rest of iterator [5,6]
terminate = true;
return Some(n);
}
if terminate {
return Some(n);
}
if conditional(n) {
return Some(n);
}
None // odd
})
.for_each(|n| {
sum += n;
});
println!("sum (2+4+5+6): {:?}", sum);
}
输出:
sum (2+4+5+6): 17
游乐场连接
有没有办法用更简洁的方式写这篇文章?一旦达到*n == 4
条件,我想使迭代器短路。
有很多方法可以解决这个问题。
这里有一对:
fn conditional(n: &i64) -> bool {
// a lot of code here which is omitted for brevity
n % 2 == 0
}
fn main() {
let buf = vec![1, 2, 3, 4, 5, 6];
let sum = buf
.iter()
.fold((0, false), |(mut sum, mut terminate), value| {
if *value == 4 {
terminate = true;
}
if terminate || conditional(value) {
sum += *value;
}
(sum, terminate)
})
.0;
println!("sum (2+4+5+6): {:?}", sum);
}
sum (2+4+5+6): 17
或者使用filter
和有状态闭包:
fn conditional(n: &i64) -> bool {
// a lot of code here which is omitted for brevity
n % 2 == 0
}
fn main() {
let buf = vec![1, 2, 3, 4, 5, 6];
let sum: i64 = buf
.iter()
.filter({
let mut terminate = false;
move |&value| {
terminate || {
if *value == 4 {
terminate = true;
}
conditional(value)
}
}
})
.sum();
println!("sum (2+4+5+6): {:?}", sum);
}
sum (2+4+5+6): 17
您可以使用filter()
:
buf.iter().filter(|n| {
if **n == 4 {
terminate = true;
}
terminate || conditional(n)
})
和sum()
代替for_each()
:
let sum = buf
.iter()
.filter(|n| {
if **n == 4 {
terminate = true;
}
terminate || conditional(n)
})
.sum::<i64>();