繁体   English   中英

如何在 Rust 中的索引上过滤向量

[英]How can I filter a vector on an index in Rust

我有一个Vec<f64> ,我试图说出向量的每个第 7 个元素,直到我用完界限,进入另一个Vec<f64> 我想也许我可以创建一个我想要的元素的索引,然后根据它进行过滤。 但我似乎无法直接或间接地做到这一点。 我试过的

let x: Vec<f64> = (1..200)
.map(|x| (x as f64)/(200 as f64))
.collect();

let y: Vec<f64> = x
.enumerate()
.filter(|&(i, _)| i % 7 == 0 )
.map(|(_, e)| e)
.collect();

但这不适用于编译错误enumerate method cannot be called on Vec<f64> due to unsatisfied trait bounds 我还找到了一个保留方法,但没有看到将它应用于索引而不是元素的方法。 对 SO 的强大搜索令人惊讶地没有产生任何结果。

感谢您的评论,将所有内容拼凑在一起,为社区提供更完整的答案。 假设这是 Vec: let x: Vec<f64> = (1..10).map(|x| (x as f64)/(10 as f64)).collect();

要根据索引过滤向量,首先我们用 into_iter 创建一个迭代器,然后枚举它以获取索引,然后应用过滤器,然后使用映射删除索引,最后将其收集到 f64 向量。

let y: Vec<f64> = x
.into_iter()
.enumerate()
.filter(|&(i, _)| i % 2 == 0 )
.map(|(_, e)| e)
.collect();

如果y的范围比x的范围短,并且如果您在y中有较大的值(例如字符串),则最好将y设为引用向量而不是值。

let y: Vec<&f64> = x
.iter()
.enumerate()
.filter(|&(i, _)| i % 2 == 0 )
.map(|(_, e)| e)
.collect();

这里的主要区别是使用iter()而不是iter_into() rust book中的这一页解释了它:

iter 方法在不可变引用上生成一个迭代器。 如果我们想创建一个获取 v1 所有权并返回拥有值的迭代器,我们可以调用into_iter而不是iter 类似地,如果我们想迭代可变引用,我们可以调用iter_mut而不是iter

现在,对于这个特定问题,可能不需要对索引应用过滤器。 正如下面 Chayim 所指出的,一种更简单的方法是

let y: Vec<_> = x.into_iter().step_by(2).collect();

我还找到了一个保留方法,但没有看到将它应用于索引而不是元素的方法。

虽然Vec::retain没有为您提供任何类型的索引,但它需要一个FnMut并记录为按顺序操作:

该方法在原地操作,按原始顺序对每个元素只访问一次,并保留保留元素的顺序。

所以你可以自己跟踪索引:

let mut idx = 0;
x.retain(|_| {
    let v = idx;
    idx += 1;
    v % 2 == 0
});

或者在这里你可以通过一个简单的切换来专注于:

let mut keep = false;
x.retain(|_| {
    keep = !keep;
    keep
});

请注意,有一个专门的迭代器适配器step_by()

let y: Vec<_> = x.into_iter().step_by(7).collect();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM