如何在Rust中去除数组重复元素?代码问题排查及无外部依赖实现方案
在Rust中实现数组去重的几种方法
让我们一步步解决你遇到的问题,同时给出几种符合需求的实现方式:
一、为什么你的itertools代码没生效?
你遇到的第一个问题是arr.iter().unique()没有修改原数组,这是因为:
itertools::unique()返回的是一个迭代器,它不会原地修改原数组,你需要把这个迭代器的结果收集到新的容器中才能得到去重后的数组。- 另外,
arr.iter()产生的是引用类型(&u8),所以你需要用cloned()或copied()把引用转换成实际的数值,再收集成Vec。
修正后的itertools版本代码如下:
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); // 收集迭代器结果到新Vec,cloned()将&u8转为u8 let unique_arr: Vec<_> = arr.iter().unique().cloned().collect(); println!("unique {:?}", unique_arr); }
二、为什么arr.sort().iter().unique()报错?
arr.sort()是一个原地排序方法,它的返回值是单元类型()(没有返回值),所以你不能直接链式调用iter()。正确的写法是把排序和后续操作分开:
// 先排序,再处理 arr.sort(); let unique_arr: Vec<_> = arr.iter().unique().cloned().collect();
三、无需外部依赖的"排序+去重"方法
Rust标准库的Vec自带了dedup()方法,它可以移除数组中连续的重复元素。结合sort()先把重复元素集中到一起,就能实现无依赖的去重:
use rand::{thread_rng, Rng}; 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.sort(); arr.dedup(); println!("unique {:?}", arr); }
这个方法的优点是:
- 完全依赖标准库,不需要额外引入crate
- 原地修改数组,内存开销小
- 实现简洁
如果不想修改原数组,可以先克隆一份再处理:
let mut sorted_arr = arr.clone(); sorted_arr.sort(); sorted_arr.dedup(); println!("unique {:?}", sorted_arr);
四、标准库实现保持原顺序的去重
如果你需要保留元素的首次出现顺序,同时不想依赖itertools,可以用标准库的HashSet来实现:
use rand::{thread_rng, Rng}; use std::collections::HashSet; fn main() { let mut arr: Vec<u8> = Vec::new(); for _ in 0..10 { arr.push(thread_rng().gen_range(0..10)) } println!("random {:?}", arr); let mut seen = HashSet::new(); // filter保留首次出现的元素,因为insert返回true仅当元素未存在 let unique_arr: Vec<_> = arr.into_iter() .filter(|&x| seen.insert(x)) .collect(); println!("unique {:?}", unique_arr); }
这个方法通过HashSet跟踪已经出现过的元素,确保只保留每个元素的第一次出现,同时完全使用标准库。
内容的提问来源于stack exchange,提问作者HelloWorldEngineer
相关产品推荐
相关产品推荐

