Skip to content

Instantly share code, notes, and snippets.

@lfairy lfairy/dedup.rs
Last active Jan 31, 2019

Embed
What would you like to do?
.dedup() on iterators
use std::iter::Peekable;
trait IteratorDedup: Iterator + Sized {
fn dedup(self) -> Dedup<Self> where Self::Item: PartialEq {
Dedup {
inner: self.peekable(),
emit: true,
}
}
}
impl<I> IteratorDedup for I where I: Iterator + Sized {}
struct Dedup<I: Iterator> {
inner: Peekable<I>,
emit: bool,
}
impl<I> Iterator for Dedup<I> where I: Iterator, <I as Iterator>::Item: PartialEq {
type Item = <I as Iterator>::Item;
fn next(&mut self) -> Option<<I as Iterator>::Item> {
let result =
if self.emit {
self.inner.next()
} else {
let first = match self.inner.next() {
None => return None,
Some(first) => first,
};
self.inner.find(|item| first != *item)
};
self.emit = result.as_ref() != self.inner.peek();
result
}
}
fn dedup_test<T: PartialEq + Clone>(input: &[T]) -> Vec<T> {
input.iter().cloned().dedup().collect()
}
#[test]
fn smoke_test() {
assert_eq!(dedup_test::<i32>(&[]), []);
assert_eq!(dedup_test(&[1]), [1]);
assert_eq!(dedup_test(&[1, 2, 3]), [1, 2, 3]);
assert_eq!(dedup_test(&[1, 1, 2, 3]), [1, 2, 3]);
assert_eq!(dedup_test(&[1, 2, 2, 3, 3]), [1, 2, 3]);
assert_eq!(dedup_test(&[1, 2, 2, 2, 3]), [1, 2, 3]);
assert_eq!(dedup_test(&[1, 1, 1, 1, 1]), [1]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.