From eb5ac84c8e14184b9b76fe088b5f5120e887ee35 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 17:42:31 -0400 Subject: [PATCH 1/3] iterator: add a `find` adaptor --- src/libstd/iterator.rs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index e65904a68992e..7aa273f7cd81d 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -308,6 +308,9 @@ pub trait IteratorUtil { /// assert!(!it.any_(|&x| *x == 3)); /// ~~~ fn any_(&mut self, f: &fn(A) -> bool) -> bool; + + /// Return the first element satisfying the specified predicate + fn find(&mut self, predicate: &fn(&A) -> bool) -> Option; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -421,7 +424,7 @@ impl> IteratorUtil for T { None => { break; } } } - return accum; + accum } /// Count the number of items yielded by an iterator @@ -431,13 +434,22 @@ impl> IteratorUtil for T { #[inline(always)] fn all(&mut self, f: &fn(A) -> bool) -> bool { for self.advance |x| { if !f(x) { return false; } } - return true; + true } #[inline(always)] fn any_(&mut self, f: &fn(A) -> bool) -> bool { for self.advance |x| { if f(x) { return true; } } - return false; + false + } + + /// Return the first element satisfying the specified predicate + #[inline(always)] + fn find(&mut self, predicate: &fn(&A) -> bool) -> Option { + for self.advance |x| { + if predicate(&x) { return Some(x) } + } + None } } @@ -1055,4 +1067,12 @@ mod tests { assert!(!v.iter().any_(|&x| x > 100)); assert!(!v.slice(0, 0).iter().any_(|_| fail!())); } + + #[test] + fn test_find() { + let v = &[1, 3, 9, 27, 103, 14, 11]; + assert_eq!(*v.iter().find(|x| *x & 1 == 0).unwrap(), 14); + assert_eq!(*v.iter().find(|x| *x % 3 == 0).unwrap(), 3); + assert!(v.iter().find(|x| *x % 12 == 0).is_none()); + } } From 2df66a84cd64211c22e58c48df07ce63bf5469a3 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 17:56:26 -0400 Subject: [PATCH 2/3] iterator: add a `position` adaptor --- src/libstd/iterator.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 7aa273f7cd81d..a8969f1da6e27 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -311,6 +311,9 @@ pub trait IteratorUtil { /// Return the first element satisfying the specified predicate fn find(&mut self, predicate: &fn(&A) -> bool) -> Option; + + /// Return the index of the first element satisfying the specified predicate + fn position(&mut self, predicate: &fn(A) -> bool) -> Option; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -451,6 +454,19 @@ impl> IteratorUtil for T { } None } + + /// Return the index of the first element satisfying the specified predicate + #[inline] + fn position(&mut self, predicate: &fn(A) -> bool) -> Option { + 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 @@ mod tests { 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()); + } } From 79cd2dbe72781e14adb321483cfed1d861a598ce Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Jun 2013 18:02:05 -0400 Subject: [PATCH 3/3] iterator: work around method resolve bug --- src/libstd/iterator.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index a8969f1da6e27..a505c55235986 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -310,10 +310,10 @@ pub trait IteratorUtil { fn any_(&mut self, f: &fn(A) -> bool) -> bool; /// Return the first element satisfying the specified predicate - fn find(&mut self, predicate: &fn(&A) -> bool) -> Option; + fn find_(&mut self, predicate: &fn(&A) -> bool) -> Option; /// Return the index of the first element satisfying the specified predicate - fn position(&mut self, predicate: &fn(A) -> bool) -> Option; + fn position_(&mut self, predicate: &fn(A) -> bool) -> Option; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -448,7 +448,7 @@ impl> IteratorUtil for T { /// Return the first element satisfying the specified predicate #[inline(always)] - fn find(&mut self, predicate: &fn(&A) -> bool) -> Option { + fn find_(&mut self, predicate: &fn(&A) -> bool) -> Option { for self.advance |x| { if predicate(&x) { return Some(x) } } @@ -457,7 +457,7 @@ impl> IteratorUtil for T { /// Return the index of the first element satisfying the specified predicate #[inline] - fn position(&mut self, predicate: &fn(A) -> bool) -> Option { + fn position_(&mut self, predicate: &fn(A) -> bool) -> Option { let mut i = 0; for self.advance |x| { if predicate(x) { @@ -1087,16 +1087,16 @@ mod tests { #[test] fn test_find() { let v = &[1, 3, 9, 27, 103, 14, 11]; - assert_eq!(*v.iter().find(|x| *x & 1 == 0).unwrap(), 14); - assert_eq!(*v.iter().find(|x| *x % 3 == 0).unwrap(), 3); - assert!(v.iter().find(|x| *x % 12 == 0).is_none()); + assert_eq!(*v.iter().find_(|x| *x & 1 == 0).unwrap(), 14); + 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()); + 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()); } }