如何在 Rust 中删除数组中的重复项?

Don*_*al0 2 arrays sorting vector rust

我生成了一个数字数组。我想删除重复项。在 javascript 中,我可以使用[...new Set(arr)]并完成工作。

在 Rust 中,到目前为止我还没有找到实现这一目标的简单方法。

我写过:

use rand::{thread_rng, Rng};
use itertools::Itertools;

fn main() {
    let mut arr:Vec<u8> = Vec::new();
    for _ in 0..10 {
        arr.push(thread_rng().gen_range(0..10))
    }
    println!("random {:?}", arr);
    arr.iter().unique();
    println!("unique {:?}", arr);
}
Run Code Online (Sandbox Code Playgroud)

输出是:

random [7, 0, 3, 6, 7, 7, 1, 1, 8, 6]
unique [7, 0, 3, 6, 7, 7, 1, 1, 8, 6]
Run Code Online (Sandbox Code Playgroud)

所以我试图在另一个变量中获得“无重复”结果:

random [7, 0, 3, 6, 7, 7, 1, 1, 8, 6]
unique [7, 0, 3, 6, 7, 7, 1, 1, 8, 6]
Run Code Online (Sandbox Code Playgroud)

结果是:

Unique { iter: UniqueBy { iter: Iter([1, 2, 0, 0, 7, 0, 2, 2, 1, 6]), used: {} } }
Run Code Online (Sandbox Code Playgroud)

另外,在执行删除重复项之前我似乎无法对数组进行排序。此代码返回错误:no method named 'iter' found for unit type '()' in the current scope method not found in '()'

let res = &arr.iter().unique();
Run Code Online (Sandbox Code Playgroud)

另外,也许有一种方法可以在没有外部板条箱的情况下实现排序+唯一值输出?

Bla*_*ans 8

使用标准库

通常,对数组进行排序是一种消除重复数据的好方法,但是,除非您使用基数排序(这不是 Rust 使用的排序方法),否则最好按照您在 JS 中所做的那样进行。这是 Rust 的等价物:

let a_vector = vec![7, 0, 3, 6, 7, 7, 1, 1, 8, 6];
let uniqued_vector = a_vector
    .into_iter()
    .collect::<HashSet<_>>()
    .into_iter()
    .collect::<Vec<_>>();
Run Code Online (Sandbox Code Playgroud)

这会将你的数组变成一个迭代器,然后将该迭代器变成 a HashSet(这将对其进行重复数据删除),然后再次返回到迭代器形式,最后变成一个数组。

在操场上看到它。


如果您想知道为什么我们必须在这些迭代器表示之间来回切换,那是因为它们是 Rust 用于将任何数据类型转换为任何其他数据类型的“接口”,非常高效,同时允许您在此过程中执行一些操作容易地。在这里,我们实际上不需要做任何比转换更多的事情,所以这就是为什么它看起来有点冗长。

使用itertools板条箱

itertools板条箱提供了用于迭代器的实用程序(与我们用作数据类型之间转换的接口相同)。然而,迭代器的一个特点是它们在某种程度上是惰性的,因为它们本身并不是用于存储信息的数据类型。它们仅表示通过可迭代接口对集合执行的操作。因此,您实际上需要将迭代器转换回可用的集合(或以任何方式使用它),否则它将什么也不做(字面意思)。

所以你的代码的正确版本可能是

let a_vector = vec![7, 0, 3, 6, 7, 7, 1, 1, 8, 6];
let uniqued_vector = a_vector
    .into_iter()
    .unique()
    .collect::<Vec<_>>();
Run Code Online (Sandbox Code Playgroud)

您不需要对任何内容进行排序,因为在内部,.unique()其工作原理与第一个实现非常相似。

对数组进行排序

如前所述,对数组进行排序很好,因此您可能仍然想这样做。然而,与以前的解决方案不同,这不仅仅涉及迭代器,因为您无法对迭代器进行排序(特征没有提供这样的方法Iterator,也没有产生的实际类型a_vector.into_iter())!但是,一旦对数组进行了排序,您可能需要对其进行重复数据删除,即删除连续的重复项,而该Iterator特征也没有提供这一点。然而,这两个实际上都是由 提供的Vec,所以解决方案很简单:

let mut a_vector = vec![7, 0, 3, 6, 7, 7, 1, 1, 8, 6];
a_vector.sort_unstable();
a_vector.dedup();
Run Code Online (Sandbox Code Playgroud)

然后a_vector包含独特的元素。

请注意,只有当您仅使用标准库时,这才是正确的。Itertools 提供了排序方法和重复数据删除方法,因此itertools您可以这样做:

let a_vector = vec![7, 0, 3, 6, 7, 7, 1, 1, 8, 6];
let uniqued_vector = a_vector
    .into_iter()
    .sorted_unstable()
    .dedup()
    .collect::<Vec<_>>();
Run Code Online (Sandbox Code Playgroud)

但此时你最好使用.unique().


.iter()如果您想知道和之间的区别.into_iter(),请参阅此问题