假设我有一个向量,它上面有一个过滤器,我想把它分解成两个向量:一个过滤向量和它的补码.我认为有两种方法可以做到这一点.第一个是for循环:

let vct: Vec<u32> = vec![1, 3, 4, 7, 9, 10, 12];
let filter = |x| x % 3 == 0;

let mut filtered: Vec<u32> = Vec::new();
let mut complement: Vec<u32> = Vec::new();
for v in vct {
    if filter(v) {
        filtered.push(v);
    } else {
        complement.push(v);
    }
}

println!("{:?}", filtered);   //[3, 9, 12]
println!("{:?}", complement); //[1, 4, 7, 10]

这似乎很有效,但不必要地冗长(并为向量添加了不必要的可变性).另一种是使用迭代器的简单方法:

let vct: Vec<u32> = vec![1, 3, 4, 7, 9, 10, 12];
let filter = |x:&&u32| *x % 3 == 0;

let filtered: Vec<u32> = vct.iter().filter(filter).cloned().collect();
let complement: Vec<u32> = vct.into_iter().filter(|x| !filter(&x)).collect();

println!("{:?}", filtered);   //[3, 9, 12]
println!("{:?}", complement); //[1, 4, 7, 10]

它有一个更清晰的意图,也不太冗长(除了filter定义/用法,这有点难看),但在数组上迭代twice次,这似乎是不必要的.

这两种解决方案似乎都不是最优的.

是否有一种惯用的and有效方法(无需重新迭代)将向量拆分为过滤器及其补码?

推荐答案

您try 执行的操作称为partitioning.您可以使用Iterator.partition():

let vct: Vec<u32> = vec![1, 3, 4, 7, 9, 10, 12];
let filter: fn(u32) -> bool = |x| x % 3 == 0;

let (filtered, complement): (Vec<u32>, Vec<u32>) = vct.iter().partition(|x| filter(**x));

assert_eq!(&[3, 9, 12], filtered.as_slice());
assert_eq!(&[1, 4, 7, 10], complement.as_slice());

Playground

Rust相关问答推荐

trait声明中的生命周期参数

如何访问Rust存储值的内存地址

如果成员都实现特征,是否在多态集合上实现部分重叠的特征?

限制未使用的泛型导致编译错误

在我的Cargo 中,当我在建筑物中使用时,找不到我可以在产品包中使用的 crate .r我如何解决这个问题?

在IntoIter上调用.by_ref().Take().rev()时会发生什么情况

循环访问枚举中的不同集合

如何在Rust中基于字符串 Select struct ?

Rust ndarray:如何从索引中 Select 数组的行

如何设置activx websocket actorless的消息大小限制?

使用占位符获取用户输入

为什么某些类型参数仅在特征边界中使用的代码在没有 PhantomData 的情况下进行编译?

我可以禁用发布模式的开发依赖功能吗?

在不安全的 Rust 中存储对 struct 内部数据的静态引用是否合法?

为什么不能在 Rust 中声明静态或常量 std::path::Path 对象?

Rust 中 `Option` 的内存开销不是常量

将文件的第一行分别读取到文件的其余部分的最有效方法是什么?

通用类型,不同于输入类型,作为函数的返回值

Rust 中的运行时插件

加入动态数量的期货