Skip to content

Commit c5bfe23

Browse files
committed
Add position_{max, max_by_key, max_by, min, min_by_key, min_by}
The max functions use Iterator::max_by, while the min functions use Iterator::min_by.
1 parent c620ae8 commit c5bfe23

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed

src/lib.rs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2254,6 +2254,172 @@ pub trait Itertools : Iterator {
22542254
)
22552255
}
22562256

2257+
/// Return the position of the maximum element in the iterator.
2258+
///
2259+
/// If several elements are equally maximum, the position of the
2260+
/// last of them is returned.
2261+
///
2262+
/// # Examples
2263+
///
2264+
/// ```
2265+
/// use itertools::Itertools;
2266+
///
2267+
/// let a: [i32; 0] = [];
2268+
/// assert_eq!(a.iter().position_max(), None);
2269+
///
2270+
/// let a = [-3, 0, 1, 5, -10];
2271+
/// assert_eq!(a.iter().position_max(), Some(3));
2272+
///
2273+
/// let a = [1, 1, -1, -1];
2274+
/// assert_eq!(a.iter().position_max(), Some(1));
2275+
/// ```
2276+
fn position_max(self) -> Option<usize>
2277+
where Self: Sized, Self::Item: Ord
2278+
{
2279+
self.enumerate()
2280+
.max_by(|x, y| Ord::cmp(&x.1, &y.1))
2281+
.map(|x| x.0)
2282+
}
2283+
2284+
/// Return the position of the maximum element in the iterator, as
2285+
/// determined by the specified function.
2286+
///
2287+
/// If several elements are equally maximum, the position of the
2288+
/// last of them is returned.
2289+
///
2290+
/// # Examples
2291+
///
2292+
/// ```
2293+
/// use itertools::Itertools;
2294+
///
2295+
/// let a: [i32; 0] = [];
2296+
/// assert_eq!(a.iter().position_max_by_key(|x| x.abs()), None);
2297+
///
2298+
/// let a = [-3_i32, 0, 1, 5, -10];
2299+
/// assert_eq!(a.iter().position_max_by_key(|x| x.abs()), Some(4));
2300+
///
2301+
/// let a = [1_i32, 1, -1, -1];
2302+
/// assert_eq!(a.iter().position_max_by_key(|x| x.abs()), Some(3));
2303+
/// ```
2304+
fn position_max_by_key<K, F>(self, mut key: F) -> Option<usize>
2305+
where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
2306+
{
2307+
self.enumerate()
2308+
.max_by(|x, y| Ord::cmp(&key(&x.1), &key(&y.1)))
2309+
.map(|x| x.0)
2310+
}
2311+
2312+
/// Return the position of the maximum element in the iterator, as
2313+
/// determined by the specified comparison function.
2314+
///
2315+
/// If several elements are equally maximum, the position of the
2316+
/// last of them is returned.
2317+
///
2318+
/// # Examples
2319+
///
2320+
/// ```
2321+
/// use itertools::Itertools;
2322+
///
2323+
/// let a: [i32; 0] = [];
2324+
/// assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), None);
2325+
///
2326+
/// let a = [-3_i32, 0, 1, 5, -10];
2327+
/// assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), Some(3));
2328+
///
2329+
/// let a = [1_i32, 1, -1, -1];
2330+
/// assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), Some(1));
2331+
/// ```
2332+
fn position_max_by<F>(self, mut compare: F) -> Option<usize>
2333+
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
2334+
{
2335+
self.enumerate()
2336+
.max_by(|x, y| compare(&x.1, &y.1))
2337+
.map(|x| x.0)
2338+
}
2339+
2340+
/// Return the position of the minimum element in the iterator.
2341+
///
2342+
/// If several elements are equally minimum, the position of the
2343+
/// first of them is returned.
2344+
///
2345+
/// # Examples
2346+
///
2347+
/// ```
2348+
/// use itertools::Itertools;
2349+
///
2350+
/// let a: [i32; 0] = [];
2351+
/// assert_eq!(a.iter().position_min(), None);
2352+
///
2353+
/// let a = [-3, 0, 1, 5, -10];
2354+
/// assert_eq!(a.iter().position_min(), Some(4));
2355+
///
2356+
/// let a = [1, 1, -1, -1];
2357+
/// assert_eq!(a.iter().position_min(), Some(2));
2358+
/// ```
2359+
fn position_min(self) -> Option<usize>
2360+
where Self: Sized, Self::Item: Ord
2361+
{
2362+
self.enumerate()
2363+
.min_by(|x, y| Ord::cmp(&x.1, &y.1))
2364+
.map(|x| x.0)
2365+
}
2366+
2367+
/// Return the position of the minimum element in the iterator, as
2368+
/// determined by the specified function.
2369+
///
2370+
/// If several elements are equally minimum, the position of the
2371+
/// first of them is returned.
2372+
///
2373+
/// # Examples
2374+
///
2375+
/// ```
2376+
/// use itertools::Itertools;
2377+
///
2378+
/// let a: [i32; 0] = [];
2379+
/// assert_eq!(a.iter().position_min_by_key(|x| x.abs()), None);
2380+
///
2381+
/// let a = [-3_i32, 0, 1, 5, -10];
2382+
/// assert_eq!(a.iter().position_min_by_key(|x| x.abs()), Some(1));
2383+
///
2384+
/// let a = [1_i32, 1, -1, -1];
2385+
/// assert_eq!(a.iter().position_min_by_key(|x| x.abs()), Some(0));
2386+
/// ```
2387+
fn position_min_by_key<K, F>(self, mut key: F) -> Option<usize>
2388+
where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
2389+
{
2390+
self.enumerate()
2391+
.min_by(|x, y| Ord::cmp(&key(&x.1), &key(&y.1)))
2392+
.map(|x| x.0)
2393+
}
2394+
2395+
/// Return the position of the minimum element in the iterator, as
2396+
/// determined by the specified comparison function.
2397+
///
2398+
/// If several elements are equally minimum, the position of the
2399+
/// first of them is returned.
2400+
///
2401+
/// # Examples
2402+
///
2403+
/// ```
2404+
/// use itertools::Itertools;
2405+
///
2406+
/// let a: [i32; 0] = [];
2407+
/// assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), None);
2408+
///
2409+
/// let a = [-3_i32, 0, 1, 5, -10];
2410+
/// assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), Some(4));
2411+
///
2412+
/// let a = [1_i32, 1, -1, -1];
2413+
/// assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), Some(2));
2414+
/// ```
2415+
fn position_min_by<F>(self, mut compare: F) -> Option<usize>
2416+
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
2417+
{
2418+
self.enumerate()
2419+
.min_by(|x, y| compare(&x.1, &y.1))
2420+
.map(|x| x.0)
2421+
}
2422+
22572423
/// If the iterator yields exactly one element, that element will be returned, otherwise
22582424
/// an error will be returned containing an iterator that has the same output as the input
22592425
/// iterator.

0 commit comments

Comments
 (0)