From b4cea351ba9df84efbff56d7bd79cd52704592d6 Mon Sep 17 00:00:00 2001 From: gifnksm Date: Fri, 17 May 2013 23:54:58 +0900 Subject: [PATCH] libcore: Add `IteratorUtil::fold`, `count` --- src/libcore/iterator.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 14d6083067a9..58850190d8b1 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -50,6 +50,8 @@ pub trait IteratorUtil { fn nth(&mut self, n: uint) -> A; fn first(&mut self) -> A; fn last(&mut self) -> A; + fn fold(&mut self, start: B, f: &fn(B, A) -> B) -> B; + fn count(&mut self) -> uint; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -184,6 +186,23 @@ impl> IteratorUtil for T { for self.advance |e| { elm = e; } return elm; } + + /// Reduce an iterator to an accumulated value + #[inline] + fn fold(&mut self, init: B, f: &fn(B, A) -> B) -> B { + let mut accum = init; + loop { + match self.next() { + Some(x) => { accum = f(accum, x); } + None => { break; } + } + } + return accum; + } + + /// Count the number of an iterator elemenrs + #[inline(always)] + fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) } } pub struct ChainIterator { @@ -648,4 +667,12 @@ mod tests { let v: &[uint] = &[]; v.iter().last(); } + + #[test] + fn test_iterator_count() { + let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert_eq!(v.slice(0, 4).iter().count(), 4); + assert_eq!(v.slice(0, 10).iter().count(), 10); + assert_eq!(v.slice(0, 0).iter().count(), 0); + } }