Composable internal iterators
Internal iterators are functions implementing the protocol used by the for
loop.
An internal iterator takes fn(...) -> bool
as a parameter, with returning false
used to signal breaking out of iteration. The adaptors in the module work with any such iterator, not just ones tied to specific traits. For example:
println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
An external iterator object implementing the interface in the iterator
module can be used as an internal iterator by calling the advance
method. For example:
let xs = [0u, 1, 2, 3, 4, 5];
let ys = [30, 40, 50, 60];
let mut it = xs.iter().chain(ys.iter());
for it.advance |&x: &uint| {
println(x.to_str());
}
Internal iterators provide a subset of the functionality of an external iterator. It's not possible to interleave them to implement algorithms like zip
, union
and merge
. However, they're often much easier to implement.
FromIter
Times
all
- Return true if predicate
is true for all values yielded by an internal iterator.any
- Return true if predicate
is true for any values yielded by an internal iterator.find
- Return the first element where predicate
returns true
fold
- Reduce an iterator to an accumulated value.fold_ref
- Reduce an iterator to an accumulated value.max
- Return the largest item yielded by an iteratormin
- Return the smallest item yielded by an iteratorproduct
- Return the product of the items yielded by an iterator.sum
- Return the sum of the items yielding by an iterator.FromIter
from_iter
fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> Self
Build a container with elements from an internal iterator.
let xs = ~[1, 2, 3];
let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) };
assert_eq!(xs, ys);
Times
times
fn times(&self, it: &fn() -> bool) -> bool
all
fn all<T>(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool) -> bool) ->
bool
Return true if predicate
is true for all values yielded by an internal iterator.
assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
any
fn any<T>(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool) -> bool) ->
bool
Return true if predicate
is true for any values yielded by an internal iterator.
Example:
let xs = ~[1u, 2, 3, 4, 5];
assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f)));
assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f)));
find
fn find<T>(predicate: &fn(&T) -> bool, iter: &fn(f: &fn(T) -> bool) -> bool)
-> Option<T>
Return the first element where predicate
returns true
. Return None
if no element is found.
let xs = ~[1u, 2, 3, 4, 5, 6];
assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4);
fold
fn fold<T,
U>(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U))
-> T
Reduce an iterator to an accumulated value.
assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
fold_ref
fn fold_ref<T,
U>(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool,
f: &fn(&mut T, &U)) -> T
Reduce an iterator to an accumulated value.
fold_ref
is usable in some generic functions where fold
is too lenient to type-check, but it forces the iterator to yield borrowed pointers.
fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
}
max
fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T>
Return the largest item yielded by an iterator. Return None
if the iterator is empty.
let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15);
min
fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T>
Return the smallest item yielded by an iterator. Return None
if the iterator is empty.
let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &-5);
product
fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T
Return the product of the items yielded by an iterator.
let xs: ~[int] = ~[1, 2, 3, 4];
assert_eq!(do product |f| { xs.iter().advance(f) }, 24);
sum
fn sum<T: Zero + Add<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T
Return the sum of the items yielding by an iterator.
let xs: ~[int] = ~[1, 2, 3, 4];
assert_eq!(do sum |f| { xs.iter().advance(f) }, 10);