1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
// Licensed under the Apache License, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 or the MIT license // http://opensource.org/licenses/MIT, at your // option. This file may not be copied, modified, or distributed // except according to those terms. use ord_subset_trait::*; use ord_var::*; ///////////////////////////////////////////////////////////////////// pub trait OrdSubsetIterExt: Iterator //where Self::Item: OrdSubset { /// Consumes the entire iterator to return the maximum element. /// Values outside the ordered subset as given by `.is_outside_order()` are ignored. /// /// Returns the last element if the comparison determines multiple elements to be equally maximum. /// /// # Example /// /// ``` /// use ord_subset::OrdSubsetIterExt; /// /// let vec = vec![2.0, 3.0, 5.0, std::f64::NAN]; /// let max = vec.iter().ord_subset_max().unwrap(); /// assert_eq!(&5.0, max); /// ``` #[inline] fn ord_subset_max(self) -> Option<Self::Item> where Self: Sized, Self::Item: OrdSubset, { self.filter_map(OrdVar::new_checked) .max() .map(OrdVar::into_inner) // Option<OrdVar<Item>> => Option<Item> } /// Consumes the entire iterator to return the minimum element. /// Values outside the ordered subset as given by `.is_outside_order()` are ignored. /// /// Returns the first element if the comparison determines multiple elements to be equally minimum. /// /// # Example /// /// ``` /// use ord_subset::OrdSubsetIterExt; /// /// let vec = vec![2.0, 3.0, 5.0, std::f64::NAN]; /// let min = vec.iter().ord_subset_min().unwrap(); /// assert_eq!(&2.0, min); /// ``` #[inline] fn ord_subset_min(self) -> Option<Self::Item> where Self: Sized, Self::Item: OrdSubset, { self.filter_map(OrdVar::new_checked) .min() .map(OrdVar::into_inner) // Option<OrdVar<Item>> => Option<Item> } /// Returns the element that gives the minimum value from the specified function. /// Values outside the ordered subset as given by `.is_outside_order()` on the mapped value are ignored. /// /// Returns the first element if the comparison determines multiple elements to be equally minimum. /// /// # Example /// /// ``` /// extern crate ord_subset; /// use ord_subset::OrdSubsetIterExt; /// /// fn main() { /// let vec = vec![2.0, 3.0, 5.0, std::f64::NAN]; /// let min_by = vec.iter().ord_subset_min_by_key(|num| num.recip()).unwrap(); /// assert_eq!(&5.0, min_by); /// } /// ``` #[inline] fn ord_subset_min_by_key<F, B>(self, mut f: F) -> Option<Self::Item> where F: FnMut(&Self::Item) -> B, B: OrdSubset, Self: Sized, { // Ok < Err, always self.min_by_key(|it| OrdVar::new_checked(f(it)).ok_or(())) } /// Returns the element that gives the maximum value from the specified function. /// Values outside the ordered subset as given by `.is_outside_order()` on the mapped value are ignored. /// /// Returns the last element if the comparison determines multiple elements to be equally maximum. #[inline] fn ord_subset_max_by_key<F, B>(self, mut f: F) -> Option<Self::Item> where F: FnMut(&Self::Item) -> B, B: OrdSubset, Self: Sized, { // Some > None, always self.max_by_key(|it| OrdVar::new_checked(f(it))) } } impl<T: ?Sized + Iterator> OrdSubsetIterExt for T {}