diff options
Diffstat (limited to 'src/unique_impl.rs')
-rw-r--r-- | src/unique_impl.rs | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/src/unique_impl.rs b/src/unique_impl.rs index cf8675c..14c14fc 100644 --- a/src/unique_impl.rs +++ b/src/unique_impl.rs @@ -54,7 +54,7 @@ impl<I, V, F> Iterator for UniqueBy<I, V, F> { type Item = I::Item; - fn next(&mut self) -> Option<I::Item> { + fn next(&mut self) -> Option<Self::Item> { while let Some(v) = self.iter.next() { let key = (self.f)(&v); if self.used.insert(key, ()).is_none() { @@ -76,13 +76,29 @@ 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<Self::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 { type Item = I::Item; - fn next(&mut self) -> Option<I::Item> { + fn next(&mut self) -> Option<Self::Item> { while let Some(v) = self.iter.iter.next() { if let Entry::Vacant(entry) = self.iter.used.entry(v) { let elt = entry.key().clone(); @@ -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<Self::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. |