我有一个Vec<T>
,其元素与模式匹配。我想删除与模式匹配的元素的所有尾随实例。
例如,我有Vec<i32>
,模式为(|x| x == 0)
。如果输入为:vec![0, 1, 0, 2, 3, 0, 0]
,则输出应为:vec![0, 1, 0, 2, 3]
要做到这一点,我试过:
fn main() {
let mut vec = vec![0, 1, 0, 2, 3, 0, 0];
vec = vec.into_iter().rev().skip_while(|&x| x == 0).rev();
}
但是我得到了这些编译错误:
error[E0277]: the trait bound `std::iter::SkipWhile<std::iter::Rev<std::vec::IntoIter<{integer}>>, [closure@src/main.rs:3:44: 3:55]>: std::iter::DoubleEndedIterator` is not satisfied
--> src/main.rs:3:57
|
3 | vec = vec.into_iter().rev().skip_while(|&x| x == 0).rev();
| ^^^ the trait `std::iter::DoubleEndedIterator` is not implemented for `std::iter::SkipWhile<std::iter::Rev<std::vec::IntoIter<{integer}>>, [closure@src/main.rs:3:44: 3:55]>`
error[E0308]: mismatched types
--> src/main.rs:3:11
|
3 | vec = vec.into_iter().rev().skip_while(|&x| x == 0).rev();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::vec::Vec`, found struct `std::iter::Rev`
|
= note: expected type `std::vec::Vec<{integer}>`
found type `std::iter::Rev<std::iter::SkipWhile<std::iter::Rev<std::vec::IntoIter<{integer}>>, [closure@src/main.rs:3:44: 3:55]>>`
奇怪的是,DoubleEndedIterator
是为SkipWhile
实施的。实际上,SkipWhile
甚至实现了rev()
。 See here
我做错了什么?有更好的方法吗?
答案 0 :(得分:5)
用于反转的迭代器适配器仅适用于可以从两端中的任何一端遍历的迭代器(例如,它是DoubleEndedIterator
)。虽然原始版本就属于这种情况,但从我们加入skip_while
之时起就不再可能了。为了遵循这种方法,你必须收集反向矢量的其余部分,然后再反转。
let mut vec = vec![0, 1, 0, 2, 3, 0, 0];
if let Some(i) = vec.iter().rposition(|x| *x != 0) {
let new_len = i + 1;
vec.truncate(new_len);
}
...或者只是抓住一片:
let piece = &vec[..new_len];
答案 1 :(得分:4)
如错误消息所示:
DoubleEndedIterator
未实现特征SkipWhile<...>
- 请查看SkipWhile
的实施情况:
pub struct SkipWhile<I, P> {
iter: I,
flag: bool,
predicate: P,
}
你无法反转从SkipWhile
构建的迭代器,因为当你添加从前面和后面拉出的能力时,它无法跟踪是否跳过了“当前”项。
Vec
,找到结构Rev
- 您仍然有一个迭代器,但是您试图将它存储在必须存储Vec
的位置。你不能把类型A放在需要类型B的地方。fn main() {
let mut vec = vec![0, 1, 0, 2, 3, 0, 0];
vec = vec.into_iter().rev().skip_while(|&x| x == 0).collect();
vec.reverse();
println!("{:?}", vec);
assert_eq!(vec, [0, 1, 0, 2, 3]);
}
DoubleEndedIterator
已针对SkipWhile
实施。
事实并非如此。如果您查看SkipWhile
的文档,则不会列出它实现DoubleEndedIterator
。以下是它实现的特征示例:FusedIterator
。
事实上,
SkipWhile
甚至实现了rev()
实际上并非如此。 Iterator::rev
仅在Self
(SkipWhile
)实施DoubleEndedIterator
的条件下实施,而不是fn rev(self) -> Rev<Self>
where
Self: DoubleEndedIterator,
。
https://address.com/page/#client/side/route
答案 2 :(得分:2)
为了开始,这是一个非常狡猾的解决方案:
fn main() {
let mut vec = vec![0, 1, 0, 2, 3, 0, 0];
vec = vec.into_iter().rev().skip_while(|&x| x == 0).collect();
vec = vec.into_iter().rev().collect();
}