@@ -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