]> git.lizzy.rs Git - rust.git/commitdiff
iter: add max and min functions
authorDaniel Micay <danielmicay@gmail.com>
Tue, 30 Apr 2013 17:28:20 +0000 (13:28 -0400)
committerDaniel Micay <danielmicay@gmail.com>
Tue, 30 Apr 2013 18:14:55 +0000 (14:14 -0400)
src/libcore/iter.rs

index 6f3c6890228acdbf282eb23b39e480945054e6da..8fc2db6d6f19a9289b281bd4d630347c98ad7777 100644 (file)
@@ -41,6 +41,7 @@
 
 */
 
+use cmp::Ord;
 use option::{Option, Some, None};
 
 pub trait Times {
@@ -107,8 +108,7 @@ pub fn all<T>(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool {
 }
 
 /**
- * Return the first element where `predicate` returns `true`, otherwise return `Npne` if no element
- * is found.
+ * Return the first element where `predicate` returns `true`. Return `None` if no element is found.
  *
  * # Example:
  *
@@ -127,6 +127,58 @@ pub fn find<T>(predicate: &fn(&T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> Opti
     None
 }
 
+/**
+ * Return the largest item yielded by an iterator. Return `None` if the iterator is empty.
+ *
+ * # Example:
+ *
+ * ~~~~
+ * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
+ * assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
+ * ~~~~
+ */
+#[inline]
+pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool)) -> Option<T> {
+    let mut result = None;
+    for iter |x| {
+        match result {
+            Some(ref mut y) => {
+                if x > *y {
+                    *y = x;
+                }
+            }
+            None => result = Some(x)
+        }
+    }
+    result
+}
+
+/**
+ * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty.
+ *
+ * # Example:
+ *
+ * ~~~~
+ * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
+ * assert_eq!(max(|f| xs.each(f)).unwrap(), &-5);
+ * ~~~~
+ */
+#[inline]
+pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool)) -> Option<T> {
+    let mut result = None;
+    for iter |x| {
+        match result {
+            Some(ref mut y) => {
+                if x < *y {
+                    *y = x;
+                }
+            }
+            None => result = Some(x)
+        }
+    }
+    result
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -157,4 +209,16 @@ fn test_find() {
         let xs = ~[1u, 2, 3, 4, 5, 6];
         assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
     }
+
+    #[test]
+    fn test_max() {
+        let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
+        assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
+    }
+
+    #[test]
+    fn test_min() {
+        let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
+        assert_eq!(min(|f| xs.each(f)).unwrap(), &-5);
+    }
 }