iter_first_max/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3
4use core::cmp::Ordering;
5
6#[doc = include_str!("../README.md")]
7pub trait IterFirstMaxExt: Iterator + Sized {
8    /// Get max element, if equal, return the first equal element
9    #[inline]
10    fn first_max(self) -> Option<Self::Item>
11    where Self::Item: Ord,
12    {
13        self.first_max_by(Ord::cmp)
14    }
15
16    /// Get max element, if equal, return the first equal element
17    #[inline]
18    fn first_max_by<F>(self, mut f: F) -> Option<Self::Item>
19    where F: FnMut(&Self::Item, &Self::Item) -> Ordering,
20    {
21        self.reduce(move |a, b| {
22            if f(&a, &b).is_lt() {
23                b
24            } else {
25                a
26            }
27        })
28    }
29
30    /// Get max element, if key equal, return the first key equal element
31    #[inline]
32    fn first_max_by_key<B, F>(self, mut f: F) -> Option<Self::Item>
33    where F: FnMut(&Self::Item) -> B,
34          B: Ord,
35    {
36        #[inline]
37        fn cmp<B: Ord, T>((a, _): &(B, T), (b, _): &(B, T)) -> Ordering {
38            a.cmp(b)
39        }
40        self.map(move |elem| (f(&elem), elem))
41            .first_max_by(cmp)?
42            .1
43            .into()
44    }
45}
46impl<I: Iterator> IterFirstMaxExt for I { }
47
48
49/// Similar the [`IterFirstMaxExt`]
50///
51///
52/// ```rust
53/// use iter_first_max::IterLastMinExt as _;
54///
55/// let arr = [(1, 0), (1, 1), (1, 2), (2, 3), (2, 4)];
56/// let first = arr.iter().min_by_key(|n| n.0);
57/// let last  = arr.iter().last_min_by_key(|n| n.0);
58///
59/// assert_eq!(first, Some(&(1, 0)));
60/// assert_eq!(last,  Some(&(1, 2)));
61/// ```
62pub trait IterLastMinExt: Iterator + Sized {
63    /// Get min element, if equal, return the last equal element
64    #[inline]
65    fn last_min(self) -> Option<Self::Item>
66    where Self::Item: Ord,
67    {
68        self.last_min_by(Ord::cmp)
69    }
70
71    /// Get min element, if equal, return the last equal element
72    #[inline]
73    fn last_min_by<F>(self, mut f: F) -> Option<Self::Item>
74    where F: FnMut(&Self::Item, &Self::Item) -> Ordering,
75    {
76        self.reduce(move |a, b| {
77            if f(&a, &b).is_ge() {
78                b
79            } else {
80                a
81            }
82        })
83    }
84
85    /// Get min element, if key equal, return the last key equal element
86    #[inline]
87    fn last_min_by_key<B, F>(self, mut f: F) -> Option<Self::Item>
88    where F: FnMut(&Self::Item) -> B,
89          B: Ord,
90    {
91        #[inline]
92        fn cmp<B: Ord, T>((a, _): &(B, T), (b, _): &(B, T)) -> Ordering {
93            a.cmp(b)
94        }
95        self.map(move |elem| (f(&elem), elem))
96            .last_min_by(cmp)?
97            .1
98            .into()
99    }
100}
101impl<I: Iterator> IterLastMinExt for I { }