Skip to content

Commit 9d9bf4d

Browse files
committed
Implement DedupBy in terms of CoalesceBy
1 parent 0205bd5 commit 9d9bf4d

File tree

1 file changed

+15
-56
lines changed

1 file changed

+15
-56
lines changed

src/adaptors/mod.rs

Lines changed: 15 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ mod multi_product;
99
pub use self::multi_product::*;
1010

1111
use std::fmt;
12-
use std::mem::replace;
1312
use std::iter::{Fuse, Peekable, FromIterator, FusedIterator};
1413
use std::marker::PhantomData;
1514
use crate::size_hint;
@@ -733,11 +732,21 @@ impl<I, F, T> Iterator for CoalesceBy<I, F, T>
733732
///
734733
/// See [`.dedup_by()`](../trait.Itertools.html#method.dedup_by) or [`.dedup()`](../trait.Itertools.html#method.dedup) for more information.
735734
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
736-
pub struct DedupBy<I, Pred>
737-
where I: Iterator
735+
pub type DedupBy<I, Pred> = CoalesceBy<I, DedupPred2CoalescePred<Pred>, <I as Iterator>::Item>;
736+
737+
#[derive(Clone)]
738+
pub struct DedupPred2CoalescePred<DP>(DP);
739+
740+
impl<DP, T> CoalescePredicate<T, T> for DedupPred2CoalescePred<DP>
741+
where DP: DedupPredicate<T>
738742
{
739-
iter: CoalesceCore<I, I::Item>,
740-
dedup_pred: Pred,
743+
fn coalesce_pair(&mut self, t: T, item: T) -> Result<T, (T, T)> {
744+
if self.0.dedup_pair(&t, &item) {
745+
Ok(t)
746+
} else {
747+
Err((t, item))
748+
}
749+
}
741750
}
742751

743752
pub trait DedupPredicate<T> { // TODO replace by Fn(&T, &T)->bool once Rust supports it
@@ -764,13 +773,6 @@ impl<T, F: FnMut(&T, &T)->bool> DedupPredicate<T> for F {
764773
/// See [`.dedup()`](../trait.Itertools.html#method.dedup) for more information.
765774
pub type Dedup<I>=DedupBy<I, DedupEq>;
766775

767-
impl<I: Clone, Pred: Clone> Clone for DedupBy<I, Pred>
768-
where I: Iterator,
769-
I::Item: Clone,
770-
{
771-
clone_fields!(iter, dedup_pred);
772-
}
773-
774776
/// Create a new `DedupBy`.
775777
pub fn dedup_by<I, Pred>(mut iter: I, dedup_pred: Pred) -> DedupBy<I, Pred>
776778
where I: Iterator,
@@ -780,7 +782,7 @@ pub fn dedup_by<I, Pred>(mut iter: I, dedup_pred: Pred) -> DedupBy<I, Pred>
780782
last: iter.next(),
781783
iter,
782784
},
783-
dedup_pred,
785+
f: DedupPred2CoalescePred(dedup_pred),
784786
}
785787
}
786788

@@ -791,49 +793,6 @@ pub fn dedup<I>(iter: I) -> Dedup<I>
791793
dedup_by(iter, DedupEq)
792794
}
793795

794-
impl<I, Pred> fmt::Debug for DedupBy<I, Pred>
795-
where I: Iterator + fmt::Debug,
796-
I::Item: fmt::Debug,
797-
{
798-
debug_fmt_fields!(Dedup, iter);
799-
}
800-
801-
impl<I, Pred> Iterator for DedupBy<I, Pred>
802-
where I: Iterator,
803-
Pred: DedupPredicate<I::Item>,
804-
{
805-
type Item = I::Item;
806-
807-
fn next(&mut self) -> Option<Self::Item> {
808-
let ref mut dedup_pred = self.dedup_pred;
809-
self.iter.next_with(|x, y| {
810-
if dedup_pred.dedup_pair(&x, &y) { Ok(x) } else { Err((x, y)) }
811-
})
812-
}
813-
814-
fn size_hint(&self) -> (usize, Option<usize>) {
815-
self.iter.size_hint()
816-
}
817-
818-
fn fold<Acc, G>(self, mut accum: Acc, mut f: G) -> Acc
819-
where G: FnMut(Acc, Self::Item) -> Acc,
820-
{
821-
if let Some(mut last) = self.iter.last {
822-
let mut dedup_pred = self.dedup_pred;
823-
accum = self.iter.iter.fold(accum, |acc, elt| {
824-
if dedup_pred.dedup_pair(&elt, &last) {
825-
acc
826-
} else {
827-
f(acc, replace(&mut last, elt))
828-
}
829-
});
830-
f(accum, last)
831-
} else {
832-
accum
833-
}
834-
}
835-
}
836-
837796
/// An iterator adaptor that removes repeated duplicates, while keeping a count of how many
838797
/// repeated elements were present. This will determine equality using a comparison function.
839798
///

0 commit comments

Comments
 (0)