about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-02-12 22:30:58 -0800
committerBrian Anderson <banderson@mozilla.com>2012-02-12 22:30:58 -0800
commit8309d50ff4ead4dd58b8f3c8388d5668e2e0d152 (patch)
tree59542dccabc38031c794e2a178c7bc9a38a41db4
parente360ddbd65e2501028f80e17a1ec7ad92904f39c (diff)
downloadrust-8309d50ff4ead4dd58b8f3c8388d5668e2e0d152.tar.gz
rust-8309d50ff4ead4dd58b8f3c8388d5668e2e0d152.zip
core: Add iter::filter_map
-rw-r--r--src/libcore/iter.rs25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index e1f9c4ec548..e9327a26017 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -57,6 +57,16 @@ fn filter<A,IA:iterable<A>>(self: IA, prd: fn@(A) -> bool, blk: fn(A)) {
     }
 }
 
+fn filter_map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> option<B>,
+                                  blk: fn(B)) {
+    self.iter {|a|
+        alt cnv(a) {
+          some(b) { blk(b) }
+          none { }
+        }
+    }
+}
+
 fn map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> B, blk: fn(B)) {
     self.iter {|a|
         let b = cnv(a);
@@ -189,6 +199,21 @@ fn test_filter_on_uint_range() {
 }
 
 #[test]
+fn test_filter_map() {
+    fn negativate_the_evens(&&i: int) -> option<int> {
+        if i % 2 == 0 {
+            some(-i)
+        } else {
+            none
+        }
+    }
+
+    let l = to_list(bind filter_map(
+        bind int::range(0, 5, _), negativate_the_evens, _));
+    assert l == [0, -2, -4];
+}
+
+#[test]
 fn test_flat_map_with_option() {
     fn if_even(&&i: int) -> option<int> {
         if (i % 2) == 0 { some(i) }