Skip to content

Commit 086b7d2

Browse files
committed
Add find_or_first method to Itertools trait
1 parent 4a52f3c commit 086b7d2

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,6 +1750,29 @@ pub trait Itertools : Iterator {
17501750
self.find_map(|x| if predicate(&x) { Some(x) } else { prev = Some(x); None })
17511751
.or(prev)
17521752
}
1753+
/// Find the value of the first element satisfying a predicate or return the first element, if any.
1754+
///
1755+
/// The iterator is not advanced past the first element found.
1756+
///
1757+
/// ```
1758+
/// use itertools::Itertools;
1759+
///
1760+
/// let numbers = [1, 2, 3, 4];
1761+
/// assert_eq!(numbers.iter().find_or_first(|&&x| x > 5), Some(&1));
1762+
/// assert_eq!(numbers.iter().find_or_first(|&&x| x > 2), Some(&3));
1763+
/// assert_eq!(std::iter::empty::<i32>().find_or_first(|&x| x > 5), None);
1764+
/// ```
1765+
fn find_or_first<P>(mut self, mut predicate: P) -> Option<Self::Item>
1766+
where Self: Sized,
1767+
P: FnMut(&Self::Item) -> bool,
1768+
{
1769+
let first = self.next()?;
1770+
Some(if predicate(&first) {
1771+
first
1772+
} else {
1773+
self.find(|x| predicate(&x)).unwrap_or(first)
1774+
})
1775+
}
17531776
/// Returns `true` if the given item is present in this iterator.
17541777
///
17551778
/// This method is short-circuiting. If the given item is present in this

0 commit comments

Comments
 (0)