From 4b87c7e3b419345e2d0fd35987a2e012b1e95a5e Mon Sep 17 00:00:00 2001 From: philipp Date: Sat, 20 Aug 2016 15:12:50 +0200 Subject: [PATCH 1/3] Introduce max_by/min_by on iterators --- src/libcore/iter/iterator.rs | 51 ++++++++++++++++++++++++++++++++++++ src/libcoretest/iter.rs | 12 +++++++++ src/libcoretest/lib.rs | 2 ++ 3 files changed, 65 insertions(+) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 6b01ccaceea2f..e25920fae0744 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1664,6 +1664,31 @@ pub trait Iterator { .map(|(_, x)| x) } + /// Returns the element that gives the maximum value with respect to the + /// specified comparison function. + /// + /// Returns the rightmost element if the comparison determines two elements + /// to be equally maximum. + /// + /// # Examples + /// + /// ``` + /// let a = [-3_i32, 0, 1, 5, -10]; + /// assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5); + /// ``` + #[inline] + #[unstable(feature = "iter_max_by", issue="1722")] + fn max_by(self, mut compare: F) -> Option + where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, + { + select_fold1(self, + |_| (), + // switch to y even if it is only equal, to preserve + // stability. + |_, x, _, y| Ordering::Greater != compare(x, y)) + .map(|(_, x)| x) + } + /// Returns the element that gives the minimum value from the /// specified function. /// @@ -1688,6 +1713,32 @@ pub trait Iterator { .map(|(_, x)| x) } + /// Returns the element that gives the minimum value with respect to the + /// specified comparison function. + /// + /// Returns the latest element if the comparison determines two elements + /// to be equally minimum. + /// + /// # Examples + /// + /// ``` + /// let a = [-3_i32, 0, 1, 5, -10]; + /// assert_eq!(*a.iter().min_by(|x, y| x.cmp(y)).unwrap(), -10); + /// ``` + #[inline] + #[unstable(feature = "iter_min_by", issue="1722")] + fn min_by(self, mut compare: F) -> Option + where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, + { + select_fold1(self, + |_| (), + // switch to y even if it is strictly smaller, to + // preserve stability. + |_, x, _, y| Ordering::Greater == compare(x, y)) + .map(|(_, x)| x) + } + + /// Reverses an iterator's direction. /// /// Usually, iterators iterate from left to right. After using `rev()`, diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index a2848faa105e9..27eb25537f31b 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -664,12 +664,24 @@ fn test_max_by_key() { assert_eq!(*xs.iter().max_by_key(|x| x.abs()).unwrap(), -10); } +#[test] +fn test_max_by() { + let xs: &[isize] = &[-3, 0, 1, 5, -10]; + assert_eq!(*xs.iter().max_by(|x, y| x.abs().cmp(&y.abs())).unwrap(), -10); +} + #[test] fn test_min_by_key() { let xs: &[isize] = &[-3, 0, 1, 5, -10]; assert_eq!(*xs.iter().min_by_key(|x| x.abs()).unwrap(), 0); } +#[test] +fn test_min_by() { + let xs: &[isize] = &[-3, 0, 1, 5, -10]; + assert_eq!(*xs.iter().min_by(|x, y| x.abs().cmp(&y.abs())).unwrap(), 0); +} + #[test] fn test_by_ref() { let mut xs = 0..10; diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 9428b4096bfec..b4c94509477a3 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -33,6 +33,8 @@ #![feature(try_from)] #![feature(unicode)] #![feature(unique)] +#![feature(iter_max_by)] +#![feature(iter_min_by)] extern crate core; extern crate test; From dfeb20ce60b288d62796e17831f4d5cadf6afadf Mon Sep 17 00:00:00 2001 From: philipp Date: Sun, 21 Aug 2016 13:23:39 +0200 Subject: [PATCH 2/3] Added #![feature] declarations --- src/libcore/iter/iterator.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index e25920fae0744..48ea306ce5fd0 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1673,6 +1673,7 @@ pub trait Iterator { /// # Examples /// /// ``` + /// #![feature(iter_max_by)] /// let a = [-3_i32, 0, 1, 5, -10]; /// assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5); /// ``` @@ -1722,6 +1723,7 @@ pub trait Iterator { /// # Examples /// /// ``` + /// #![feature(iter_min_by)] /// let a = [-3_i32, 0, 1, 5, -10]; /// assert_eq!(*a.iter().min_by(|x, y| x.cmp(y)).unwrap(), -10); /// ``` From 5928be1d9bcd96ce4dd7b328fe527683a4e1621f Mon Sep 17 00:00:00 2001 From: philipp Date: Mon, 29 Aug 2016 19:43:18 +0200 Subject: [PATCH 3/3] Changed issue number to 36105 --- src/libcore/iter/iterator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 48ea306ce5fd0..f530009585ece 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1678,7 +1678,7 @@ pub trait Iterator { /// assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5); /// ``` #[inline] - #[unstable(feature = "iter_max_by", issue="1722")] + #[unstable(feature = "iter_max_by", issue="36105")] fn max_by(self, mut compare: F) -> Option where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, { @@ -1728,7 +1728,7 @@ pub trait Iterator { /// assert_eq!(*a.iter().min_by(|x, y| x.cmp(y)).unwrap(), -10); /// ``` #[inline] - #[unstable(feature = "iter_min_by", issue="1722")] + #[unstable(feature = "iter_min_by", issue="36105")] fn min_by(self, mut compare: F) -> Option where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, {