iterator: add a position adaptor

This commit is contained in:
Daniel Micay
2013-06-15 17:56:26 -04:00
parent eb5ac84c8e
commit 2df66a84cd
+24
View File
@@ -311,6 +311,9 @@ fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option<B>)
/// Return the first element satisfying the specified predicate
fn find(&mut self, predicate: &fn(&A) -> bool) -> Option<A>;
/// Return the index of the first element satisfying the specified predicate
fn position(&mut self, predicate: &fn(A) -> bool) -> Option<uint>;
}
/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
@@ -451,6 +454,19 @@ fn find(&mut self, predicate: &fn(&A) -> bool) -> Option<A> {
}
None
}
/// Return the index of the first element satisfying the specified predicate
#[inline]
fn position(&mut self, predicate: &fn(A) -> bool) -> Option<uint> {
let mut i = 0;
for self.advance |x| {
if predicate(x) {
return Some(i);
}
i += 1;
}
None
}
}
/// A trait for iterators over elements which can be added together
@@ -1075,4 +1091,12 @@ fn test_find() {
assert_eq!(*v.iter().find(|x| *x % 3 == 0).unwrap(), 3);
assert!(v.iter().find(|x| *x % 12 == 0).is_none());
}
#[test]
fn test_position() {
let v = &[1, 3, 9, 27, 103, 14, 11];
assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5);
assert_eq!(v.iter().position(|x| *x % 3 == 0).unwrap(), 1);
assert!(v.iter().position(|x| *x % 12 == 0).is_none());
}
}