diff options
| author | Brian Anderson <andersrb@gmail.com> | 2012-02-12 20:05:55 -0800 |
|---|---|---|
| committer | Brian Anderson <andersrb@gmail.com> | 2012-02-12 20:05:55 -0800 |
| commit | 2784314a1ff4f9b5230abb44c86b09d74d6b5e73 (patch) | |
| tree | 006a7f7caf6e549b3e17826a92ee9657cf9cf9fe | |
| parent | 4eeb706e84bc9e32aa5057e32d567ccab2c3cc2c (diff) | |
| parent | fde719f635955b1c3d76639062410262fd0df351 (diff) | |
| download | rust-2784314a1ff4f9b5230abb44c86b09d74d6b5e73.tar.gz rust-2784314a1ff4f9b5230abb44c86b09d74d6b5e73.zip | |
Merge pull request #1826 from brson/iter
Various additions to core::iter
| -rw-r--r-- | src/libcore/iter.rs | 99 |
1 files changed, 97 insertions, 2 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 7aa08a6980c..c2fc2838d70 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -65,18 +65,43 @@ fn flat_map<A,B,IA:iterable<A>,IB:iterable<B>>( } } -fn foldl<A,B:copy,IA:iterable<A>>(self: IA, b0: B, blk: fn(B, A) -> B) -> B { - let b = b0; +fn foldl<A,B,IA:iterable<A>>(self: IA, +b0: B, blk: fn(-B, A) -> B) -> B { + let b <- b0; self.iter {|a| b = blk(b, a); } ret b; } +fn foldr<A:copy,B,IA:iterable<A>>( + self: IA, +b0: B, blk: fn(A, -B) -> B) -> B { + + let b <- b0; + reverse(self) {|a| + b = blk(a, b); + } + ret b; +} + fn to_list<A:copy,IA:iterable<A>>(self: IA) -> [A] { foldl::<A,[A],IA>(self, [], {|r, a| r + [a]}) } +// FIXME: This could be made more efficient with an riterable interface +fn reverse<A:copy,IA:iterable<A>>(self: IA, blk: fn(A)) { + vec::riter(to_list(self), blk) +} + +fn count<A,IA:iterable<A>>(self: IA, x: A) -> uint { + foldl(self, 0u) {|count, value| + if value == x { + count + 1u + } else { + count + } + } +} + fn repeat(times: uint, blk: fn()) { let i = 0u; while i < times { @@ -85,6 +110,35 @@ fn repeat(times: uint, blk: fn()) { } } +fn min<A:copy,IA:iterable<A>>(self: IA) -> A { + alt foldl::<A,option<A>,IA>(self, none) {|a, b| + alt a { + some(a_) if a_ < b { + // FIXME: Not sure if this is successfully optimized to a move + a + } + _ { some(b) } + } + } { + some(val) { val } + none { fail "min called on empty iterator" } + } +} + +fn max<A:copy,IA:iterable<A>>(self: IA) -> A { + alt foldl::<A,option<A>,IA>(self, none) {|a, b| + alt a { + some(a_) if a_ > b { + // FIXME: Not sure if this is successfully optimized to a move + a + } + _ { some(b) } + } + } { + some(val) { val } + none { fail "max called on empty iterator" } + } +} #[test] fn test_enumerate() { @@ -168,4 +222,45 @@ fn test_repeat() { assert c == [0u, 1u, 4u, 9u, 16u]; } +#[test] +fn test_min() { + assert min([5, 4, 1, 2, 3]) == 1; +} + +#[test] +#[should_fail] +#[ignore(cfg(target_os = "win32"))] +fn test_min_empty() { + min::<int, [int]>([]); +} + +#[test] +fn test_max() { + assert max([1, 2, 4, 2, 3]) == 4; +} + +#[test] +#[should_fail] +#[ignore(cfg(target_os = "win32"))] +fn test_max_empty() { + max::<int, [int]>([]); +} +#[test] +fn test_reverse() { + assert to_list(bind reverse([1, 2, 3], _)) == [3, 2, 1]; +} + +#[test] +fn test_count() { + assert count([1, 2, 1, 2, 1], 1) == 3u; +} + +#[test] +fn test_foldr() { + fn sub(&&a: int, -b: int) -> int { + a - b + } + let sum = foldr([1, 2, 3, 4], 0, sub); + assert sum == -2; +} \ No newline at end of file |
