Skip to content

Commit 14293bd

Browse files
committed
Add DoubleEndedIterator implementation for Unique and UniqueBy
1 parent 4673086 commit 14293bd

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

src/unique_impl.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ impl<I, V, F> Iterator for UniqueBy<I, V, F>
7676
}
7777
}
7878

79+
impl<I, V, F> DoubleEndedIterator for UniqueBy<I, V, F>
80+
where I: DoubleEndedIterator,
81+
V: Eq + Hash,
82+
F: FnMut(&I::Item) -> V
83+
{
84+
fn next_back(&mut self) -> Option<I::Item> {
85+
while let Some(v) = self.iter.next_back() {
86+
let key = (self.f)(&v);
87+
if self.used.insert(key, ()).is_none() {
88+
return Some(v);
89+
}
90+
}
91+
None
92+
}
93+
}
94+
7995
impl<I> Iterator for Unique<I>
8096
where I: Iterator,
8197
I::Item: Eq + Hash + Clone
@@ -104,6 +120,22 @@ impl<I> Iterator for Unique<I>
104120
}
105121
}
106122

123+
impl<I> DoubleEndedIterator for Unique<I>
124+
where I: DoubleEndedIterator,
125+
I::Item: Eq + Hash + Clone
126+
{
127+
fn next_back(&mut self) -> Option<I::Item> {
128+
while let Some(v) = self.iter.iter.next_back() {
129+
if let Entry::Vacant(entry) = self.iter.used.entry(v) {
130+
let elt = entry.key().clone();
131+
entry.insert(());
132+
return Some(elt);
133+
}
134+
}
135+
None
136+
}
137+
}
138+
107139
/// An iterator adapter to filter out duplicate elements.
108140
///
109141
/// See [`.unique()`](../trait.Itertools.html#method.unique) for more information.

tests/test_std.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,26 @@ fn unique_by() {
5959
let xs = ["aaa", "bbbbb", "aa", "ccc", "bbbb", "aaaaa", "cccc"];
6060
let ys = ["aaa", "bbbbb", "ccc"];
6161
it::assert_equal(ys.iter(), xs.iter().unique_by(|x| x[..2].to_string()));
62+
it::assert_equal(ys.iter(), xs.iter().rev().unique_by(|x| x[..2].to_string()).rev());
63+
let ys_rev = ["cccc", "aaaaa", "bbbb"];
64+
it::assert_equal(ys_rev.iter(), xs.iter().unique_by(|x| x[..2].to_string()).rev());
6265
}
6366

6467
#[test]
6568
fn unique() {
6669
let xs = [0, 1, 2, 3, 2, 1, 3];
6770
let ys = [0, 1, 2, 3];
6871
it::assert_equal(ys.iter(), xs.iter().unique());
72+
it::assert_equal(ys.iter(), xs.iter().rev().unique().rev());
73+
let ys_rev = [3, 1, 2, 0];
74+
it::assert_equal(ys_rev.iter(), xs.iter().unique().rev());
75+
6976
let xs = [0, 1];
7077
let ys = [0, 1];
7178
it::assert_equal(ys.iter(), xs.iter().unique());
79+
it::assert_equal(ys.iter(), xs.iter().rev().unique().rev());
80+
let ys_rev = [1, 0];
81+
it::assert_equal(ys_rev.iter(), xs.iter().unique().rev());
7282
}
7383

7484
#[test]

0 commit comments

Comments
 (0)