diff options
| author | gifnksm <makoto.nksm+github@gmail.com> | 2013-06-27 06:51:04 +0900 |
|---|---|---|
| committer | gifnksm <makoto.nksm+github@gmail.com> | 2013-06-27 06:55:22 +0900 |
| commit | 8edb8f6d39498476f1124ce1bb5bb4e094bde43f (patch) | |
| tree | 281bff294e7145b952774aedb60e3b7179c2e660 /src/libstd | |
| parent | 23fb2278c7c50cf5785b1c109bc399bf87fdd542 (diff) | |
| download | rust-8edb8f6d39498476f1124ce1bb5bb4e094bde43f.tar.gz rust-8edb8f6d39498476f1124ce1bb5bb4e094bde43f.zip | |
iterator: Add `IteratorUtil::max_by/min_by` method
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/iterator.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index ab433a9a79d..9e434272198 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -351,6 +351,26 @@ pub trait IteratorUtil<A> { /// Count the number of elements satisfying the specified predicate fn count(&mut self, predicate: &fn(A) -> bool) -> uint; + + /// Return the element that gives the maximum value from the specfied function + /// + /// # Example + /// + /// --- {.rust} + /// let xs = [-3, 0, 1, 5, -10]; + /// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10); + /// --- + fn max_by<B: Ord>(&mut self, f: &fn(&A) -> B) -> Option<A>; + + /// Return the element that gives the minimum value from the specfied function + /// + /// # Example + /// + /// --- {.rust} + /// let xs = [-3, 0, 1, 5, -10]; + /// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0); + /// --- + fn min_by<B: Ord>(&mut self, f: &fn(&A) -> B) -> Option<A>; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -519,6 +539,36 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T { } i } + + #[inline] + fn max_by<B: Ord>(&mut self, f: &fn(&A) -> B) -> Option<A> { + self.fold(None, |max: Option<(A, B)>, x| { + let x_val = f(&x); + match max { + None => Some((x, x_val)), + Some((y, y_val)) => if x_val > y_val { + Some((x, x_val)) + } else { + Some((y, y_val)) + } + } + }).map_consume(|(x, _)| x) + } + + #[inline] + fn min_by<B: Ord>(&mut self, f: &fn(&A) -> B) -> Option<A> { + self.fold(None, |min: Option<(A, B)>, x| { + let x_val = f(&x); + match min { + None => Some((x, x_val)), + Some((y, y_val)) => if x_val < y_val { + Some((x, x_val)) + } else { + Some((y, y_val)) + } + } + }).map_consume(|(x, _)| x) + } } /// A trait for iterators over elements which can be added together @@ -1237,4 +1287,16 @@ mod tests { assert_eq!(xs.iter().count(|x| *x == 5), 1); assert_eq!(xs.iter().count(|x| *x == 95), 0); } + + #[test] + fn test_max_by() { + let xs = [-3, 0, 1, 5, -10]; + assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10); + } + + #[test] + fn test_min_by() { + let xs = [-3, 0, 1, 5, -10]; + assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0); + } } |
