Дми*_*бин 0 string vector rust
我已经解析了一个文件,按行分割字符串,并希望在每个向量中只留下唯一的元素.我期望vec.dedup()
这样工作:
let mut vec = vec!["a", "b", "a"];
vec.dedup();
assert_eq!(vec, ["a", "b"]);
Run Code Online (Sandbox Code Playgroud)
但它失败了:
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `["a", "b", "a"]`,
right: `["a", "b"]`', src/main.rs:4:4
Run Code Online (Sandbox Code Playgroud)
如何删除重复项?
E_n*_*ate 11
如文档所述,Vec#dedup
仅从向量中删除连续元素(它比完整重复数据删除便宜得多).vec!["a", "a", "b"]
例如,如果向量是可行的.
当然,有多种潜在的解决方案.
为了获得在保留元素的原始顺序的同时去除所有重复的向量,该itertools
包提供unique
适配器.
use itertools::Itertools;
let v = vec!["b", "a", "b"];
let v: Vec<_> = v.into_iter().unique().collect();
assert_eq!(v, ["b", "a"]);
Run Code Online (Sandbox Code Playgroud)
如果元素顺序不重要,您可以先对元素进行排序,然后调用重复数据删除.
let mut v = vec!["a", "b", "a"];
v.sort_unstable();
v.dedup();
assert_eq!(v, ["a", "b"]);
Run Code Online (Sandbox Code Playgroud)
如果快速元素查找很重要,您也可以考虑使用集合类型,例如HashSet
.
let v: HashSet<_> = ["a", "b", "a"].iter().cloned().collect();
let v2: HashSet<_> = ["b", "a"].iter().cloned().collect();
assert_eq!(v, v2);
Run Code Online (Sandbox Code Playgroud)
lje*_*drz 11
另一个答案指出 aHashSet
是没有重复的集合的更好选择,我同意。这显示了如何Vec
使用 的该属性直接对 a进行重复数据删除HashMap
,而不对第Vec
一个使用的进行排序std::vec::Vec::dedup
。
use std::hash::Hash;
use std::collections::HashSet;
fn dedup<T: Eq + Hash + Copy>(v: &mut Vec<T>) { // note the Copy constraint
let mut uniques = HashSet::new();
v.retain(|e| uniques.insert(*e));
}
fn main() {
let mut v = vec!["a", "b", "a"];
dedup(&mut v);
assert_eq!(&v, &vec!["a", "b"]);
}
Run Code Online (Sandbox Code Playgroud)
这是一个快速 (O(n)) 解决方案,但创建它HashSet
需要一些额外的内存。