use std::hash::Hash;
use crate::small::SmallSet;
pub struct DedupByKey<I: Iterator, K: Hash + Eq, F> {
iterator: I,
key_fn: F,
set: SmallSet<K>,
}
impl<I, K, F> Iterator for DedupByKey<I, K, F>
where
I: Iterator,
K: Hash + Eq + Clone,
F: FnMut(&I::Item) -> K,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
loop {
let val = self.iterator.next()?;
let key = (self.key_fn)(&val);
if !self.set.contains(&key) {
self.set.insert(key);
return Some(val);
}
}
}
}
pub trait DedupedByKey: Iterator + Sized {
fn dedup_by_key<K, F>(self, key_fn: F) -> DedupByKey<Self, K, F>
where
K: Hash + Eq + Clone,
F: FnMut(&Self::Item) -> K;
}
impl<I: Iterator + Sized> DedupedByKey for I {
fn dedup_by_key<K, F>(self, key_fn: F) -> DedupByKey<Self, K, F>
where
K: Hash + Eq + Clone,
F: FnMut(&Self::Item) -> K,
{
DedupByKey {
iterator: self,
key_fn,
set: SmallSet::new(),
}
}
}