use std::collections::HashSet;
pub trait VecExtensions<T> {
fn push_unique(&mut self, item: T)
where
T: PartialEq;
fn extend_unique(&mut self, iter: impl IntoIterator<Item = T>)
where
T: PartialEq;
fn deduplicate(&mut self)
where
T: std::hash::Hash + Eq + Copy;
}
impl<T> VecExtensions<T> for Vec<T> {
fn push_unique(&mut self, item: T)
where
T: PartialEq,
{
if !self.contains(&item) {
self.push(item);
}
}
fn extend_unique(&mut self, iter: impl IntoIterator<Item = T>)
where
T: PartialEq,
{
iter.into_iter().for_each(|i| {
self.push_unique(i);
});
}
fn deduplicate(&mut self)
where
T: std::hash::Hash + Eq + Copy,
{
let mut seen = HashSet::new();
self.retain(|t| seen.insert(*t));
}
}
#[cfg(test)]
mod test {
use crate::vec_ext::VecExtensions;
#[test]
fn deduplicate() {
let mut vec = vec![0, 1, 2, 2, 1, 0];
vec.deduplicate();
}
#[test]
fn push_unique() {
let mut vec = vec![0, 1, 2];
vec.push_unique(2);
assert_eq!(vec, vec![0, 1, 2])
}
#[test]
fn extend_unique() {
let mut vec = vec![0, 1, 2];
vec.extend_unique([1, 2, 3]);
assert_eq!(vec, vec![0, 1, 2, 3])
}
}