Last active
August 14, 2019 12:43
-
-
Save jyn514/fa4b636c37554eaf83a10c94c0f8977d to your computer and use it in GitHub Desktop.
try_max_by_key
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// short-circuiting version of iter.max_by_key | |
/// | |
/// partially taken from https://doc.rust-lang.org/src/core/iter/traits/iterator.rs.html#2591 | |
/// | |
/// Example: | |
/// | |
/// ``` | |
/// let list = [[1, 2, 3], [5, 4, 3], [1, 1, 4]]; | |
/// assert_eq!(try_max_by_key(list.into_iter(), |vec| vec.last().ok_or(())), Some(Ok(&[1, 1, 4]))); | |
/// | |
/// let lengths = [vec![], vec![1], vec![1, 2]]; | |
/// assert_eq!(try_max_by_key(lengths.into_iter(), |vec| vec.last().ok_or(())), Some(Err(()))); | |
/// ``` | |
pub fn try_max_by_key<I, T, C, R, F>(mut iter: I, mut f: F) -> Option<Result<T, R>> | |
where | |
I: Iterator<Item = T>, | |
C: std::cmp::Ord, | |
F: FnMut(&T) -> Result<C, R>, | |
{ | |
iter.next().map(|initial| { | |
// if this gives an error, return it immediately | |
// avoids f not being called if there's only one element | |
f(&initial)?; | |
iter.try_fold(initial, |current, next| { | |
if f(¤t)? >= f(&next)? { | |
Ok(current) | |
} else { | |
Ok(next) | |
} | |
}) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment