Skip to content

Commit 9b6dfb8

Browse files
committed
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).
2 parents 3652736 + 8edb8f6 commit 9b6dfb8

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

src/libstd/iterator.rs

+62
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,26 @@ pub trait IteratorUtil<A> {
351351

352352
/// Count the number of elements satisfying the specified predicate
353353
fn count(&mut self, predicate: &fn(A) -> bool) -> uint;
354+
355+
/// Return the element that gives the maximum value from the specfied function
356+
///
357+
/// # Example
358+
///
359+
/// --- {.rust}
360+
/// let xs = [-3, 0, 1, 5, -10];
361+
/// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
362+
/// ---
363+
fn max_by<B: Ord>(&mut self, f: &fn(&A) -> B) -> Option<A>;
364+
365+
/// Return the element that gives the minimum value from the specfied function
366+
///
367+
/// # Example
368+
///
369+
/// --- {.rust}
370+
/// let xs = [-3, 0, 1, 5, -10];
371+
/// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
372+
/// ---
373+
fn min_by<B: Ord>(&mut self, f: &fn(&A) -> B) -> Option<A>;
354374
}
355375

356376
/// 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 {
519539
}
520540
i
521541
}
542+
543+
#[inline]
544+
fn max_by<B: Ord>(&mut self, f: &fn(&A) -> B) -> Option<A> {
545+
self.fold(None, |max: Option<(A, B)>, x| {
546+
let x_val = f(&x);
547+
match max {
548+
None => Some((x, x_val)),
549+
Some((y, y_val)) => if x_val > y_val {
550+
Some((x, x_val))
551+
} else {
552+
Some((y, y_val))
553+
}
554+
}
555+
}).map_consume(|(x, _)| x)
556+
}
557+
558+
#[inline]
559+
fn min_by<B: Ord>(&mut self, f: &fn(&A) -> B) -> Option<A> {
560+
self.fold(None, |min: Option<(A, B)>, x| {
561+
let x_val = f(&x);
562+
match min {
563+
None => Some((x, x_val)),
564+
Some((y, y_val)) => if x_val < y_val {
565+
Some((x, x_val))
566+
} else {
567+
Some((y, y_val))
568+
}
569+
}
570+
}).map_consume(|(x, _)| x)
571+
}
522572
}
523573

524574
/// A trait for iterators over elements which can be added together
@@ -1237,4 +1287,16 @@ mod tests {
12371287
assert_eq!(xs.iter().count(|x| *x == 5), 1);
12381288
assert_eq!(xs.iter().count(|x| *x == 95), 0);
12391289
}
1290+
1291+
#[test]
1292+
fn test_max_by() {
1293+
let xs = [-3, 0, 1, 5, -10];
1294+
assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
1295+
}
1296+
1297+
#[test]
1298+
fn test_min_by() {
1299+
let xs = [-3, 0, 1, 5, -10];
1300+
assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
1301+
}
12401302
}

0 commit comments

Comments
 (0)