Skip to content

Commit 591dd5d

Browse files
committed
Add Iterator::find_map
1 parent 14ac1b5 commit 591dd5d

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

src/libcore/iter/iterator.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,6 +1745,38 @@ pub trait Iterator {
17451745
}).break_value()
17461746
}
17471747

1748+
/// Applies function to the elements of iterator and returns
1749+
/// the first non-none result.
1750+
///
1751+
/// `iter.find_map(f)` is equivalent to `iter.filter_map(f).next()`.
1752+
///
1753+
///
1754+
/// # Examples
1755+
///
1756+
/// ```
1757+
/// #![feature(iterator_find_map)]
1758+
/// let a = ["lol", "NaN", "2", "5"];
1759+
///
1760+
/// let mut first_number = a.iter().find_map(|s| s.parse().ok());
1761+
///
1762+
/// assert_eq!(first_number, Some(2));
1763+
/// ```
1764+
#[inline]
1765+
#[unstable(feature = "iterator_find_map",
1766+
reason = "unstable new API",
1767+
issue = "49602")]
1768+
fn find_map<B, F>(&mut self, mut f: F) -> Option<B> where
1769+
Self: Sized,
1770+
F: FnMut(Self::Item) -> Option<B>,
1771+
{
1772+
self.try_for_each(move |x| {
1773+
match f(x) {
1774+
Some(x) => LoopState::Break(x),
1775+
None => LoopState::Continue(()),
1776+
}
1777+
}).break_value()
1778+
}
1779+
17481780
/// Searches for an element in an iterator, returning its index.
17491781
///
17501782
/// `position()` takes a closure that returns `true` or `false`. It applies

src/libcore/tests/iter.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,33 @@ fn test_find() {
11461146
assert!(v.iter().find(|&&x| x % 12 == 0).is_none());
11471147
}
11481148

1149+
#[test]
1150+
fn test_find_map() {
1151+
let xs: &[isize] = &[];
1152+
assert_eq!(xs.iter().find_map(half_if_even), None);
1153+
let xs: &[isize] = &[3, 5];
1154+
assert_eq!(xs.iter().find_map(half_if_even), None);
1155+
let xs: &[isize] = &[4, 5];
1156+
assert_eq!(xs.iter().find_map(half_if_even), Some(2));
1157+
let xs: &[isize] = &[3, 6];
1158+
assert_eq!(xs.iter().find_map(half_if_even), Some(3));
1159+
1160+
let xs: &[isize] = &[1, 2, 3, 4, 5, 6, 7];
1161+
let mut iter = xs.iter();
1162+
assert_eq!(iter.find_map(half_if_even), Some(1));
1163+
assert_eq!(iter.find_map(half_if_even), Some(2));
1164+
assert_eq!(iter.find_map(half_if_even), Some(3));
1165+
assert_eq!(iter.next(), Some(&7));
1166+
1167+
fn half_if_even(x: &isize) -> Option<isize> {
1168+
if x % 2 == 0 {
1169+
Some(x / 2)
1170+
} else {
1171+
None
1172+
}
1173+
}
1174+
}
1175+
11491176
#[test]
11501177
fn test_position() {
11511178
let v = &[1, 3, 9, 27, 103, 14, 11];

src/libcore/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#![feature(atomic_nand)]
5050
#![feature(reverse_bits)]
5151
#![feature(inclusive_range_fields)]
52+
#![feature(iterator_find_map)]
5253

5354
extern crate core;
5455
extern crate test;

0 commit comments

Comments
 (0)