mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 09:14:20 +00:00
Add cmp::{min_by, min_by_key, max_by, max_by_key}
This commit is contained in:
parent
2c0931e168
commit
6e5ada43bf
@ -570,7 +570,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
|
||||
#[inline]
|
||||
fn max(self, other: Self) -> Self
|
||||
where Self: Sized {
|
||||
if other >= self { other } else { self }
|
||||
max_by(self, other, Ord::cmp)
|
||||
}
|
||||
|
||||
/// Compares and returns the minimum of two values.
|
||||
@ -587,7 +587,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
|
||||
#[inline]
|
||||
fn min(self, other: Self) -> Self
|
||||
where Self: Sized {
|
||||
if self <= other { self } else { other }
|
||||
min_by(self, other, Ord::cmp)
|
||||
}
|
||||
|
||||
/// Restrict a value to a certain interval.
|
||||
@ -898,6 +898,49 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
|
||||
v1.min(v2)
|
||||
}
|
||||
|
||||
/// Returns the minimum of two values with respect to the specified comparison function.
|
||||
///
|
||||
/// Returns the first argument if the comparison determines them to be equal.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_min_max_by)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// assert_eq!(cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 1);
|
||||
/// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cmp_min_max_by", issue = "64460")]
|
||||
pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
|
||||
match compare(&v1, &v2) {
|
||||
Ordering::Less | Ordering::Equal => v1,
|
||||
Ordering::Greater => v2,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the element that gives the minimum value from the specified function.
|
||||
///
|
||||
/// Returns the first argument if the comparison determines them to be equal.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_min_max_by)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// assert_eq!(cmp::min_by_key(-2, 1, |x: &i32| x.abs()), 1);
|
||||
/// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cmp_min_max_by", issue = "64460")]
|
||||
pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
|
||||
min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
|
||||
}
|
||||
|
||||
/// Compares and returns the maximum of two values.
|
||||
///
|
||||
/// Returns the second argument if the comparison determines them to be equal.
|
||||
@ -918,6 +961,49 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
|
||||
v1.max(v2)
|
||||
}
|
||||
|
||||
/// Returns the maximum of two values with respect to the specified comparison function.
|
||||
///
|
||||
/// Returns the second argument if the comparison determines them to be equal.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_min_max_by)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// assert_eq!(cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
|
||||
/// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cmp_min_max_by", issue = "64460")]
|
||||
pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
|
||||
match compare(&v1, &v2) {
|
||||
Ordering::Less | Ordering::Equal => v2,
|
||||
Ordering::Greater => v1,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the element that gives the maximum value from the specified function.
|
||||
///
|
||||
/// Returns the second argument if the comparison determines them to be equal.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cmp_min_max_by)]
|
||||
///
|
||||
/// use std::cmp;
|
||||
///
|
||||
/// assert_eq!(cmp::max_by_key(-2, 1, |x: &i32| x.abs()), -2);
|
||||
/// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cmp_min_max_by", issue = "64460")]
|
||||
pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
|
||||
max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
|
||||
}
|
||||
|
||||
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
|
||||
mod impls {
|
||||
use crate::cmp::Ordering::{self, Less, Greater, Equal};
|
||||
|
@ -1,4 +1,4 @@
|
||||
use core::cmp::Ordering::{Less, Greater, Equal};
|
||||
use core::cmp::{self, Ordering::*};
|
||||
|
||||
#[test]
|
||||
fn test_int_totalord() {
|
||||
@ -28,6 +28,28 @@ fn test_ord_max_min() {
|
||||
assert_eq!(1.min(1), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord_min_max_by() {
|
||||
let f = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
|
||||
assert_eq!(cmp::min_by(1, -1, f), 1);
|
||||
assert_eq!(cmp::min_by(1, -2, f), 1);
|
||||
assert_eq!(cmp::min_by(2, -1, f), -1);
|
||||
assert_eq!(cmp::max_by(1, -1, f), -1);
|
||||
assert_eq!(cmp::max_by(1, -2, f), -2);
|
||||
assert_eq!(cmp::max_by(2, -1, f), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord_min_max_by_key() {
|
||||
let f = |x: &i32| x.abs();
|
||||
assert_eq!(cmp::min_by_key(1, -1, f), 1);
|
||||
assert_eq!(cmp::min_by_key(1, -2, f), 1);
|
||||
assert_eq!(cmp::min_by_key(2, -1, f), -1);
|
||||
assert_eq!(cmp::max_by_key(1, -1, f), -1);
|
||||
assert_eq!(cmp::max_by_key(1, -2, f), -2);
|
||||
assert_eq!(cmp::max_by_key(2, -1, f), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ordering_reverse() {
|
||||
assert_eq!(Less.reverse(), Greater);
|
||||
|
@ -34,6 +34,7 @@
|
||||
#![feature(iter_partition_in_place)]
|
||||
#![feature(iter_is_partitioned)]
|
||||
#![feature(iter_order_by)]
|
||||
#![feature(cmp_min_max_by)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user