Skip to content

Commit 017f987

Browse files
committed
Add find_result at Iterator
1 parent e3976ff commit 017f987

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/libcore/iter/traits/iterator.rs

+36
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,42 @@ pub trait Iterator {
19631963
}).break_value()
19641964
}
19651965

1966+
/// Applies function to the elements of iterator and returns
1967+
/// the first non-none result or the first error.
1968+
///
1969+
///
1970+
/// # Examples
1971+
///
1972+
/// ```
1973+
/// let a = ["1", "2", "lol", "NaN", "5"];
1974+
///
1975+
/// let result = a.iter().find_result(|&s| s.parse()? == 2);
1976+
///
1977+
/// assert_eq!(result, Ok(Some(&2)));
1978+
/// ```
1979+
///
1980+
/// ```
1981+
/// let a = ["1", "2", "lol", "NaN", "5"];
1982+
///
1983+
/// let result = a.iter().find_result(|&s| s.parse()? == 5);
1984+
///
1985+
/// assert!(result.is_err());
1986+
/// ```
1987+
#[inline]
1988+
#[unstable(feature = "find_result", reason = "new API", issue = "?")]
1989+
fn find_result<F, E>(&mut self, mut f: F) -> Result<Option<Self::Item>, E> where
1990+
Self: Sized,
1991+
F: FnMut(&Self::Item) -> Result<bool, E>,
1992+
{
1993+
self.try_for_each(move |x| {
1994+
match f(&x) {
1995+
Ok(false) => LoopState::Continue(()),
1996+
Ok(true) => LoopState::Break(Ok(x)),
1997+
Err(x) => LoopState::Break(Err(x)),
1998+
}
1999+
}).break_value().transpose()
2000+
}
2001+
19662002
/// Searches for an element in an iterator, returning its index.
19672003
///
19682004
/// `position()` takes a closure that returns `true` or `false`. It applies

src/libcore/tests/iter.rs

+26
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,32 @@ fn test_find_map() {
12581258
}
12591259
}
12601260

1261+
#[test]
1262+
fn test_find_result() {
1263+
let xs: &[isize] = &[];
1264+
assert_eq!(xs.iter().find_result(testfn), Ok(None));
1265+
let xs: &[isize] = &[1, 2, 3, 4];
1266+
assert_eq!(xs.iter().find_result(testfn), Ok(Some(&2)));
1267+
let xs: &[isize] = &[1, 3, 4];
1268+
assert_eq!(xs.iter().find_result(testfn), Err(()));
1269+
1270+
let xs: &[isize] = &[1, 2, 3, 4, 5, 6, 7];
1271+
let mut iter = xs.iter();
1272+
assert_eq!(iter.find_result(testfn), Ok(Some(&2)));
1273+
assert_eq!(iter.find_result(testfn), Err(()));
1274+
assert_eq!(iter.next(), Some(&5));
1275+
1276+
fn testfn(x: &&isize) -> Result<bool, ()> {
1277+
if **x == 2 {
1278+
return Ok(true);
1279+
}
1280+
if **x == 4 {
1281+
return Err(());
1282+
}
1283+
Ok(false)
1284+
}
1285+
}
1286+
12611287
#[test]
12621288
fn test_position() {
12631289
let v = &[1, 3, 9, 27, 103, 14, 11];

0 commit comments

Comments
 (0)