You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
1.1 KiB
69 lines
1.1 KiB
4 years ago
|
use super::*;
|
||
|
use std::{
|
||
|
hash::Hash,
|
||
|
collections::{HashSet, HashMap},
|
||
|
mem,
|
||
|
};
|
||
|
|
||
|
pub trait DedupFullExt
|
||
|
{
|
||
|
fn dedup_full(&mut self);
|
||
|
}
|
||
|
|
||
|
impl<T> DedupFullExt for Vec<T>
|
||
|
where T: Hash + Default + Eq
|
||
|
{
|
||
|
fn dedup_full(&mut self)
|
||
|
{
|
||
|
let mut set: HashMap<T, usize> = HashMap::new();
|
||
|
for (i,x) in (0..).zip(self.iter_mut())
|
||
|
{
|
||
|
if !set.contains_key(x) {
|
||
|
let us = mem::replace(x, Default::default());
|
||
|
set.insert(us, i);
|
||
|
}
|
||
|
}
|
||
|
// To preserve order:
|
||
|
let mut tmp = Vec::with_capacity(self.len());
|
||
|
for item in set.into_iter()
|
||
|
{
|
||
|
tmp.push(item);
|
||
|
}
|
||
|
tmp.sort_by(move |a, b| a.1.partial_cmp(&b.1).unwrap());
|
||
|
self.truncate(tmp.len());
|
||
|
for (d,s) in self.iter_mut().zip(tmp.into_iter())
|
||
|
{
|
||
|
*d = s.0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod test
|
||
|
{
|
||
|
use super::*;
|
||
|
|
||
|
#[test]
|
||
|
fn dedup_full()
|
||
|
{
|
||
|
let mut vec = vec![
|
||
|
"hello",
|
||
|
"how",
|
||
|
"are",
|
||
|
"you",
|
||
|
"hello",
|
||
|
"hello",
|
||
|
"today",
|
||
|
"today",
|
||
|
"you",
|
||
|
"how",
|
||
|
"hello",
|
||
|
];
|
||
|
|
||
|
vec.dedup_full();
|
||
|
|
||
|
assert_eq!(vec.len(), 5);
|
||
|
assert_eq!(&vec[..], &["hello","how", "are", "you", "today"]);
|
||
|
}
|
||
|
}
|