Skip to content

Commit

Permalink
Add DoubleEndedIterator implementation for Unique and UniqueBy
Browse files Browse the repository at this point in the history
  • Loading branch information
futpib committed May 26, 2020
1 parent 4673086 commit 14293bd
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/unique_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@ impl<I, V, F> Iterator for UniqueBy<I, V, F>
}
}

impl<I, V, F> DoubleEndedIterator for UniqueBy<I, V, F>
where I: DoubleEndedIterator,
V: Eq + Hash,
F: FnMut(&I::Item) -> V
{
fn next_back(&mut self) -> Option<I::Item> {
while let Some(v) = self.iter.next_back() {
let key = (self.f)(&v);
if self.used.insert(key, ()).is_none() {
return Some(v);
}
}
None
}
}

impl<I> Iterator for Unique<I>
where I: Iterator,
I::Item: Eq + Hash + Clone
Expand Down Expand Up @@ -104,6 +120,22 @@ impl<I> Iterator for Unique<I>
}
}

impl<I> DoubleEndedIterator for Unique<I>
where I: DoubleEndedIterator,
I::Item: Eq + Hash + Clone
{
fn next_back(&mut self) -> Option<I::Item> {
while let Some(v) = self.iter.iter.next_back() {
if let Entry::Vacant(entry) = self.iter.used.entry(v) {
let elt = entry.key().clone();
entry.insert(());
return Some(elt);
}
}
None
}
}

/// An iterator adapter to filter out duplicate elements.
///
/// See [`.unique()`](../trait.Itertools.html#method.unique) for more information.
Expand Down
10 changes: 10 additions & 0 deletions tests/test_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,26 @@ fn unique_by() {
let xs = ["aaa", "bbbbb", "aa", "ccc", "bbbb", "aaaaa", "cccc"];
let ys = ["aaa", "bbbbb", "ccc"];
it::assert_equal(ys.iter(), xs.iter().unique_by(|x| x[..2].to_string()));
it::assert_equal(ys.iter(), xs.iter().rev().unique_by(|x| x[..2].to_string()).rev());
let ys_rev = ["cccc", "aaaaa", "bbbb"];
it::assert_equal(ys_rev.iter(), xs.iter().unique_by(|x| x[..2].to_string()).rev());
}

#[test]
fn unique() {
let xs = [0, 1, 2, 3, 2, 1, 3];
let ys = [0, 1, 2, 3];
it::assert_equal(ys.iter(), xs.iter().unique());
it::assert_equal(ys.iter(), xs.iter().rev().unique().rev());
let ys_rev = [3, 1, 2, 0];
it::assert_equal(ys_rev.iter(), xs.iter().unique().rev());

let xs = [0, 1];
let ys = [0, 1];
it::assert_equal(ys.iter(), xs.iter().unique());
it::assert_equal(ys.iter(), xs.iter().rev().unique().rev());
let ys_rev = [1, 0];
it::assert_equal(ys_rev.iter(), xs.iter().unique().rev());
}

#[test]
Expand Down

0 comments on commit 14293bd

Please sign in to comment.