diff --git a/src/lib.rs b/src/lib.rs index 22649148f..bc2d8c2f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1730,7 +1730,49 @@ pub trait Itertools : Iterator { } None } - + /// Find the value of the first element satisfying a predicate or return the last element, if any. + /// + /// The iterator is not advanced past the first element found. + /// + /// ``` + /// use itertools::Itertools; + /// + /// let numbers = [1, 2, 3, 4]; + /// assert_eq!(numbers.iter().find_or_last(|&&x| x > 5), Some(&4)); + /// assert_eq!(numbers.iter().find_or_last(|&&x| x > 2), Some(&3)); + /// assert_eq!(std::iter::empty::().find_or_last(|&x| x > 5), None); + /// ``` + fn find_or_last

(mut self, mut predicate: P) -> Option + where Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + let mut prev = None; + self.find_map(|x| if predicate(&x) { Some(x) } else { prev = Some(x); None }) + .or(prev) + } + /// Find the value of the first element satisfying a predicate or return the first element, if any. + /// + /// The iterator is not advanced past the first element found. + /// + /// ``` + /// use itertools::Itertools; + /// + /// let numbers = [1, 2, 3, 4]; + /// assert_eq!(numbers.iter().find_or_first(|&&x| x > 5), Some(&1)); + /// assert_eq!(numbers.iter().find_or_first(|&&x| x > 2), Some(&3)); + /// assert_eq!(std::iter::empty::().find_or_first(|&x| x > 5), None); + /// ``` + fn find_or_first

(mut self, mut predicate: P) -> Option + where Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + let first = self.next()?; + Some(if predicate(&first) { + first + } else { + self.find(|x| predicate(&x)).unwrap_or(first) + }) + } /// Returns `true` if the given item is present in this iterator. /// /// This method is short-circuiting. If the given item is present in this