Skip to content

Commit 2784314

Browse files
committed
Merge pull request #1826 from brson/iter
Various additions to core::iter
2 parents 4eeb706 + fde719f commit 2784314

File tree

1 file changed

+97
-2
lines changed

1 file changed

+97
-2
lines changed

src/libcore/iter.rs

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,43 @@ fn flat_map<A,B,IA:iterable<A>,IB:iterable<B>>(
6565
}
6666
}
6767

68-
fn foldl<A,B:copy,IA:iterable<A>>(self: IA, b0: B, blk: fn(B, A) -> B) -> B {
69-
let b = b0;
68+
fn foldl<A,B,IA:iterable<A>>(self: IA, +b0: B, blk: fn(-B, A) -> B) -> B {
69+
let b <- b0;
7070
self.iter {|a|
7171
b = blk(b, a);
7272
}
7373
ret b;
7474
}
7575

76+
fn foldr<A:copy,B,IA:iterable<A>>(
77+
self: IA, +b0: B, blk: fn(A, -B) -> B) -> B {
78+
79+
let b <- b0;
80+
reverse(self) {|a|
81+
b = blk(a, b);
82+
}
83+
ret b;
84+
}
85+
7686
fn to_list<A:copy,IA:iterable<A>>(self: IA) -> [A] {
7787
foldl::<A,[A],IA>(self, [], {|r, a| r + [a]})
7888
}
7989

90+
// FIXME: This could be made more efficient with an riterable interface
91+
fn reverse<A:copy,IA:iterable<A>>(self: IA, blk: fn(A)) {
92+
vec::riter(to_list(self), blk)
93+
}
94+
95+
fn count<A,IA:iterable<A>>(self: IA, x: A) -> uint {
96+
foldl(self, 0u) {|count, value|
97+
if value == x {
98+
count + 1u
99+
} else {
100+
count
101+
}
102+
}
103+
}
104+
80105
fn repeat(times: uint, blk: fn()) {
81106
let i = 0u;
82107
while i < times {
@@ -85,6 +110,35 @@ fn repeat(times: uint, blk: fn()) {
85110
}
86111
}
87112

113+
fn min<A:copy,IA:iterable<A>>(self: IA) -> A {
114+
alt foldl::<A,option<A>,IA>(self, none) {|a, b|
115+
alt a {
116+
some(a_) if a_ < b {
117+
// FIXME: Not sure if this is successfully optimized to a move
118+
a
119+
}
120+
_ { some(b) }
121+
}
122+
} {
123+
some(val) { val }
124+
none { fail "min called on empty iterator" }
125+
}
126+
}
127+
128+
fn max<A:copy,IA:iterable<A>>(self: IA) -> A {
129+
alt foldl::<A,option<A>,IA>(self, none) {|a, b|
130+
alt a {
131+
some(a_) if a_ > b {
132+
// FIXME: Not sure if this is successfully optimized to a move
133+
a
134+
}
135+
_ { some(b) }
136+
}
137+
} {
138+
some(val) { val }
139+
none { fail "max called on empty iterator" }
140+
}
141+
}
88142

89143
#[test]
90144
fn test_enumerate() {
@@ -168,4 +222,45 @@ fn test_repeat() {
168222
assert c == [0u, 1u, 4u, 9u, 16u];
169223
}
170224

225+
#[test]
226+
fn test_min() {
227+
assert min([5, 4, 1, 2, 3]) == 1;
228+
}
229+
230+
#[test]
231+
#[should_fail]
232+
#[ignore(cfg(target_os = "win32"))]
233+
fn test_min_empty() {
234+
min::<int, [int]>([]);
235+
}
236+
237+
#[test]
238+
fn test_max() {
239+
assert max([1, 2, 4, 2, 3]) == 4;
240+
}
241+
242+
#[test]
243+
#[should_fail]
244+
#[ignore(cfg(target_os = "win32"))]
245+
fn test_max_empty() {
246+
max::<int, [int]>([]);
247+
}
171248

249+
#[test]
250+
fn test_reverse() {
251+
assert to_list(bind reverse([1, 2, 3], _)) == [3, 2, 1];
252+
}
253+
254+
#[test]
255+
fn test_count() {
256+
assert count([1, 2, 1, 2, 1], 1) == 3u;
257+
}
258+
259+
#[test]
260+
fn test_foldr() {
261+
fn sub(&&a: int, -b: int) -> int {
262+
a - b
263+
}
264+
let sum = foldr([1, 2, 3, 4], 0, sub);
265+
assert sum == -2;
266+
}

0 commit comments

Comments
 (0)