topset/
iter.rs

1use std::iter::{FusedIterator};
2use crate::TopSet;
3
4pub struct IntoIterSorted<X,C>(TopSet<X,C>)
5    where C: Fn(&X,&X) -> bool;
6
7impl<X,C> From<TopSet<X,C>> for IntoIterSorted<X,C>
8    where C: Fn(&X,&X) -> bool
9{
10    #[inline] fn from(topset: TopSet<X, C>) -> Self { Self(topset) }
11}
12
13impl<X,C> IntoIterSorted<X,C>
14    where C: Fn(&X,&X) -> bool
15{
16    #[inline] pub fn peek(&self) -> Option<&X> { self.0.peek() }
17}
18
19impl<X,C> Iterator for IntoIterSorted<X,C>
20    where C: Fn(&X,&X) -> bool
21{
22    type Item = X;
23    #[inline] fn next(&mut self) -> Option<Self::Item> { self.0.pop() }
24    #[inline] fn count(self) -> usize { self.0.len() }
25    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { (self.0.len(), Some(self.0.len())) }
26    #[inline] fn last(self) -> Option<X> {
27        self.0.heap.into_iter().reduce(|a,b| if (self.0.beat)(&a,&b) {a} else {b})
28    }
29}
30
31impl<X,C:Fn(&X,&X)->bool> FusedIterator for IntoIterSorted<X,C> { }
32
33// impl<X,C:Fn(&X,&X)->bool> TrustedLen for IntoIterSorted<X,C> { }
34
35impl<X,C> ExactSizeIterator for IntoIterSorted<X,C>
36    where C: Fn(&X,&X) -> bool
37{
38    #[inline] fn len(&self) -> usize { self.0.len() }
39
40    // #[inline] fn is_empty(&self) -> bool { self.0.is_empty() }
41}
42
43pub trait TopSetReducing
44{
45    type Item;
46
47    /// Build the top set according to the specified challenge.
48    fn topset<C>(self, n: usize, beat: C) -> TopSet<Self::Item, C>
49        where C: Fn(&Self::Item, &Self::Item) -> bool;
50
51    /// Build the top set of the greatest values.
52    #[inline]
53    #[allow(clippy::type_complexity)]
54    fn topset_greatest(self, n: usize) -> TopSet<Self::Item, fn(&Self::Item,&Self::Item)->bool>
55        where Self::Item: PartialOrd, Self: Sized
56    {
57        self.topset(n, <Self::Item as PartialOrd>::gt)
58    }
59
60    /// Build the top set of the lowest values.
61    #[inline]
62    #[allow(clippy::type_complexity)]
63    fn topset_lowest(self, n: usize) -> TopSet<Self::Item, fn(&Self::Item,&Self::Item)->bool>
64        where Self::Item: PartialOrd, Self: Sized
65    {
66        self.topset(n, <Self::Item as PartialOrd>::lt)
67    }
68}
69
70impl<I:IntoIterator> TopSetReducing for I
71{
72    type Item = I::Item;
73
74    #[inline]
75    fn topset<C>(self, n: usize, beat: C) -> TopSet<Self::Item, C>
76        where C: Fn(&Self::Item, &Self::Item) -> bool
77    {
78        self.into_iter().fold(TopSet::new(n,beat), |mut top, e| { top.insert(e); top })
79    }
80}
81
82
83#[cfg(test)]
84mod tests {
85    use crate::iter::TopSetReducing;
86
87    #[test]
88    fn lowest_cost()
89    {
90        let mut top = vec![
91            81.5, 4.5, 4., 1., 45., 22., 11., 81.5, 4.5, 4., 1., 45., 22., 11.
92        ].topset_lowest(5);
93
94        assert_eq![top.pop(), Some(4.5)];
95        assert_eq![top.pop(), Some(4.)];
96        assert_eq![top.pop(), Some(4.)];
97        assert_eq![top.pop(), Some(1.)];
98        assert_eq![top.pop(), Some(1.)];
99        assert_eq![top.pop(), None];
100    }
101
102    #[test]
103    fn greatest_score()
104    {
105        assert_eq![
106            vec![81, 5, 4, 5, 4, 1, 45, 22, 1, 5, 97, 5, 877, 12, 0]
107                .topset_greatest(5)
108                .into_iter()
109                .last(),
110            Some(877)];
111    }
112
113    #[test]
114    fn iterator()
115    {
116        let top = vec![ 4, 9, 7, 3, 4, 1 ].topset_lowest(3);
117
118        let iter = top.clone().into_iter_sorted();
119        assert_eq!( iter.len(), 3);
120        assert_eq!( iter.count(), 3);
121
122        let iter = top.into_iter_sorted();
123        assert_eq!( iter.peek(), Some(&4));
124        assert_eq!( iter.size_hint(), (3, Some(3)));
125        assert_eq!( iter.last(), Some(1));
126    }
127}