diff options
| author | bors <bors@rust-lang.org> | 2013-06-27 10:37:36 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-06-27 10:37:36 -0700 |
| commit | 9b6dfb85782a6ec50c39292626acf2c74b0ae754 (patch) | |
| tree | e76a0445582cae4f4e001cfa5f9e77bae38a10ae /src | |
| parent | 36527360a66024d0e3f971c0732efc52368afc8b (diff) | |
| parent | 8edb8f6d39498476f1124ce1bb5bb4e094bde43f (diff) | |
auto merge of #7414 : gifnksm/rust/max_by, r=catamorphism
`max_by` method returns the element that gives the maximum value from the specfied function. `max_by`/`min_by` are convenient when you want to get the value which has greatest/smallest scores. Inspired by [ruby's Enumerable module](http://ruby-doc.org/core-2.0/Enumerable.html).
Diffstat (limited to 'src')
| -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); + } } |
