Auto merge of #35856 - phimuemue:master, r=brson
Introduce max_by/min_by on iterators See https://github.com/rust-lang/rfcs/issues/1722 for reference. It seems that there is `min`, `max` (simple computation of min/max), `min_by_key`, `max_by_key` (min/max by comparing mapped values) but no `min_by` and `max_by` (min/max according to comparison function). However, e.g. on vectors or slices there is `sort`, `sort_by_key` and `sort_by`.
This commit is contained in:
commit
d128e6bc74
3 changed files with 67 additions and 0 deletions
|
@ -1657,6 +1657,32 @@ pub trait Iterator {
|
||||||
.map(|(_, x)| x)
|
.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
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![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);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "iter_max_by", issue="36105")]
|
||||||
|
fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
|
||||||
|
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
|
/// Returns the element that gives the minimum value from the
|
||||||
/// specified function.
|
/// specified function.
|
||||||
///
|
///
|
||||||
|
@ -1681,6 +1707,33 @@ pub trait Iterator {
|
||||||
.map(|(_, x)| x)
|
.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
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![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);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "iter_min_by", issue="36105")]
|
||||||
|
fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
|
||||||
|
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.
|
/// Reverses an iterator's direction.
|
||||||
///
|
///
|
||||||
/// Usually, iterators iterate from left to right. After using `rev()`,
|
/// Usually, iterators iterate from left to right. After using `rev()`,
|
||||||
|
|
|
@ -664,12 +664,24 @@ fn test_max_by_key() {
|
||||||
assert_eq!(*xs.iter().max_by_key(|x| x.abs()).unwrap(), -10);
|
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]
|
#[test]
|
||||||
fn test_min_by_key() {
|
fn test_min_by_key() {
|
||||||
let xs: &[isize] = &[-3, 0, 1, 5, -10];
|
let xs: &[isize] = &[-3, 0, 1, 5, -10];
|
||||||
assert_eq!(*xs.iter().min_by_key(|x| x.abs()).unwrap(), 0);
|
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]
|
#[test]
|
||||||
fn test_by_ref() {
|
fn test_by_ref() {
|
||||||
let mut xs = 0..10;
|
let mut xs = 0..10;
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#![feature(try_from)]
|
#![feature(try_from)]
|
||||||
#![feature(unicode)]
|
#![feature(unicode)]
|
||||||
#![feature(unique)]
|
#![feature(unique)]
|
||||||
|
#![feature(iter_max_by)]
|
||||||
|
#![feature(iter_min_by)]
|
||||||
|
|
||||||
extern crate core;
|
extern crate core;
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
Loading…
Add table
Reference in a new issue