Last active
September 7, 2016 08:08
-
-
Save jupp0r/4ab19e3e03f291d5d9fff1ee2050a330 to your computer and use it in GitHub Desktop.
Unique Iterator in Rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::HashSet; | |
use std::option::Option; | |
use std::hash::{SipHasher, Hash, Hasher}; | |
struct UniqueIterator<I> { | |
iter: I, | |
seen_items: HashSet<u64>, | |
} | |
fn hash_item<T>(item: &T) -> u64 | |
where T: Hash | |
{ | |
let mut hasher = SipHasher::new(); | |
item.hash(&mut hasher); | |
hasher.finish() | |
} | |
impl<I> Iterator for UniqueIterator<I> | |
where I: Iterator, | |
I::Item: Hash + Sized | |
{ | |
type Item = I::Item; | |
fn next(&mut self) -> Option<Self::Item> { | |
let seen_items = &mut self.seen_items; | |
match self.iter | |
.find(|x: &Self::Item| -> bool { !seen_items.contains(&hash_item(&x)) }) { | |
None => None, | |
Some(item) => { | |
seen_items.insert(hash_item(&item)); | |
Some(item) | |
} | |
} | |
} | |
} | |
trait UniqueIteratorAdapter: Iterator { | |
fn unique(self) -> UniqueIterator<Self> | |
where Self: Sized, | |
Self::Item: Hash + Sized | |
{ | |
UniqueIterator { | |
iter: self, | |
seen_items: HashSet::new(), | |
} | |
} | |
} | |
impl<I> UniqueIteratorAdapter for I where I: Iterator {} | |
fn main() { | |
let data = vec![1, 12, 15, 1, 12, 3, 5].into_iter().unique().collect::<Vec<_>>(); | |
println!("{:?}", data); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment