diff --git a/src/lib.rs b/src/lib.rs index 247e6fe81..e6cad757b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1734,6 +1734,78 @@ pub trait Itertools : Iterator { v } + /// Returns `true` if the elements of the iterator are sorted + /// in increasing order. + /// + /// ``` + /// # use itertools::Itertools; + /// let v = vec![0, 1, 2 , 3]; + /// assert!(v.iter().is_sorted()); + /// + /// let v = vec![0, 1, 2 , -1]; + /// assert!(!v.iter().is_sorted()); + /// ``` + fn is_sorted(&mut self) -> bool + where Self: Sized, + Self::Item: Ord, + { + self.is_sorted_by(|a, b| Ord::cmp(&a, &b)) + } + + /// Returns `true` if the elements of the iterator + /// are sorted according to the `comparison` function. + /// + /// ``` + /// # use itertools::Itertools; + /// # use std::cmp::Ordering; + /// // Is an iterator sorted in decreasing order? + /// fn decr(a: &T, b: &T) -> Ordering { + /// a.cmp(b).reverse() + /// } + /// + /// let v = vec![3, 2, 1 , 0]; + /// assert!(v.iter().is_sorted_by(decr)); + /// + /// let v = vec![3, 2, 1 , 4]; + /// assert!(!v.iter().is_sorted_by(decr)); + /// ``` + fn is_sorted_by(&mut self, mut compare: F) -> bool + where Self: Sized, + Self::Item: Ord, + F: FnMut(&Self::Item, &Self::Item) -> Ordering, + { + let first = self.next(); + if let Some(mut first) = first { + return self.all(|second| { + if compare(&first, &second) == Ordering::Greater { + return false; + } + first = second; + true + }); + } + true + } + + /// Returns `true` if the elements of the iterator + /// are sorted according to the `key` extraction function. + /// + /// ``` + /// # use itertools::Itertools; + /// let v = vec![0_i32, -1, 2, -3]; + /// assert!(v.iter().is_sorted_by_key(|v| v.abs())); + /// + /// let v = vec![0_i32, -1, 2, 0]; + /// assert!(!v.iter().is_sorted_by_key(|v| v.abs())); + /// ``` + fn is_sorted_by_key(&mut self, mut key: F) -> bool + where Self: Sized, + B: Ord, + F: FnMut(&Self::Item) -> B, + { + self.map(|v| key(&v)).is_sorted() + } + /// Collect all iterator elements into one of two /// partitions. Unlike `Iterator::partition`, each partition may /// have a distinct type.