我只需要找到下一个数字相同的数字:[1,2,2,3,4,4]
应该生成 [2,4]
。因为我需要查看下一个数字,所以我想我会尝试使用 Peekable
iterator并编写一个过滤器
。
fn main() {
let xs = [1, 2, 2, 3, 4, 4];
let mut iter = xs.iter().peekable();
let pairs = iter.filter(move |num| {
match iter.peek() {
Some(next) => num == next,
None => false,
}
});
for num in pairs {
println!("{}", num);
}
}
我得到一个错误:
error[E0382]: capture of moved value: `iter`
--> src/main.rs:6:15
|
5 | let pairs = iter.filter(move |num| {
| ---- value moved here
6 | match iter.peek() {
| ^^^^ value captured here after move
|
= note: move occurs because `iter` has type `std::iter::Peekable<std::slice::Iter<'_, i32>>`, which does not implement the `Copy` trait
我认为这是因为闭包正在使用iter
,但它没有借用它,它无法复制它。
我如何解决这个想在过滤器中引用迭代器的问题?
最佳答案
refer to the iterator inside a filter
我不相信你可以。当您调用 filter
时,它会取得基础迭代器的所有权:
fn filter<P>(self, predicate: P) -> Filter<Self, P>
where
P: FnMut(&Self::Item) -> bool,
一旦你这样做了,它就消失了。没有更多的 iter
。在一些类似的情况下,您可以使用 Iterator::by_ref
可变地借用迭代器,驱动它一段时间,然后再引用原来的。这在这种情况下不起作用,因为内部迭代器需要第二次可变地借用它,这是不允许的。
find only the numbers where the next number is the same.
extern crate itertools;
use itertools::Itertools;
fn main() {
let input = [1, 2, 2, 3, 4, 4];
let pairs = input
.iter()
.tuple_windows()
.filter_map(|(a, b)| if a == b { Some(a) } else { None });
let result: Vec<_> = pairs.cloned().collect();
assert_eq!(result, [2, 4]);
}
或者如果你想要只使用标准库的东西:
fn main() {
let xs = [1, 2, 2, 3, 4, 4];
let mut prev = None;
let pairs = xs.iter().filter_map(move |curr| {
let next = if prev == Some(curr) { Some(curr) } else { None };
prev = Some(curr);
next
});
let result: Vec<_> = pairs.cloned().collect();
assert_eq!(result, [2, 4]);
}
关于iterator - 如何在过滤器闭包中使用 Peekable 迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47644485/