Skip to content

Commit

Permalink
feat(corelib): Iterator::find (#7151)
Browse files Browse the repository at this point in the history
  • Loading branch information
julio4 authored Jan 28, 2025
1 parent ad32a91 commit e9f7f14
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
53 changes: 53 additions & 0 deletions corelib/src/iter/traits/iterator.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,59 @@ pub trait Iterator<T> {
}
}

/// Searches for an element of an iterator that satisfies a predicate.
///
/// `find()` takes a closure that returns `true` or `false`. It applies
/// this closure to each element of the iterator as a snapshot, and if
/// any of them return `true`, then `find()` returns [`Some(element)`].
/// If they all return `false`, it returns [`None`].
///
/// `find()` is short-circuiting; in other words, it will stop processing
/// as soon as the closure returns `true`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let mut iter = array![1, 2, 3].into_iter();
///
/// assert_eq!(iter.find(|x| *x == 2), Option::Some(2));
///
/// assert_eq!(iter.find(|x| *x == 5), Option::None);
/// ```
///
/// Stopping at the first `true`:
///
/// ```
/// let mut iter = array![1, 2, 3].into_iter();
///
/// assert_eq!(iter.find(|x| *x == 2), Option::Some(2));
///
/// // we can still use `iter`, as there are more elements.
/// assert_eq!(iter.next(), Option::Some(3));
/// ```
fn find<
P,
+core::ops::Fn<P, (@Self::Item,)>[Output: bool],
+Destruct<P>,
+Destruct<T>,
+Destruct<Self::Item>,
>(
ref self: T, predicate: P,
) -> Option<
Self::Item,
> {
match Self::next(ref self) {
Option::None => Option::None,
Option::Some(x) => if predicate(@x) {
Option::Some(x)
} else {
Self::find(ref self, predicate)
},
}
}

/// 'Zips up' two iterators into a single iterator of pairs.
///
/// `zip()` returns a new iterator that will iterate over two other
Expand Down
11 changes: 11 additions & 0 deletions corelib/src/test/iter_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,14 @@ fn test_iter_accum_product() {
assert_eq!((1_usize..=1).into_iter().product(), 1);
assert_eq!((1_usize..=5).into_iter().product(), 120);
}

#[test]
fn test_iter_find() {
let mut iter = array![1, 2, 3].into_iter();
assert_eq!(iter.find(|x| *x == 2), Option::Some(2));
assert_eq!(iter.find(|x| *x == 5), Option::None);

let mut iter = array![1, 2, 3].into_iter();
assert_eq!(iter.find(|x| *x == 2), Option::Some(2));
assert_eq!(iter.next(), Option::Some(3));
}

0 comments on commit e9f7f14

Please sign in to comment.