Skip to content

Commit a6a4c60

Browse files
authored
Merge pull request #12 from Palladinium/flat-map
Add flat_map
2 parents 055eb72 + d328939 commit a6a4c60

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

src/lib.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,22 @@ pub trait StreamingIterator {
150150
}
151151
}
152152

153+
/// Creates an iterator which flattens iterators obtained by applying a closure to elements.
154+
/// Note that the returned iterators must be streaming iterators.
155+
#[inline]
156+
fn flat_map<J, F>(self, f: F) -> FlatMap<Self, J, F>
157+
where
158+
Self: Sized,
159+
J: StreamingIterator,
160+
F: FnMut(&Self::Item) -> J,
161+
{
162+
FlatMap {
163+
it: self,
164+
f,
165+
sub_iter: None,
166+
}
167+
}
168+
153169
/// Returns the first element of the iterator that satisfies the predicate.
154170
#[inline]
155171
fn find<F>(&mut self, mut f: F) -> Option<&Self::Item>
@@ -856,6 +872,40 @@ where
856872
}
857873
}
858874

875+
/// A streaming iterator that maps elements to iterators with a closure and then yields the
876+
/// concatenation of the obtained iterators
877+
#[derive(Debug)]
878+
pub struct FlatMap<I, J, F> {
879+
it: I,
880+
f: F,
881+
sub_iter: Option<J>,
882+
}
883+
884+
impl<I, J, F> StreamingIterator for FlatMap<I, J, F>
885+
where
886+
I: StreamingIterator,
887+
F: FnMut(&I::Item) -> J,
888+
J: StreamingIterator,
889+
{
890+
type Item = J::Item;
891+
892+
#[inline]
893+
fn advance(&mut self) {
894+
while self.sub_iter.as_mut().and_then(J::next).is_none() {
895+
if let Some(item) = self.it.next() {
896+
self.sub_iter = Some((self.f)(item));
897+
} else {
898+
break;
899+
}
900+
}
901+
}
902+
903+
#[inline]
904+
fn get(&self) -> Option<&Self::Item> {
905+
self.sub_iter.as_ref().and_then(J::get)
906+
}
907+
}
908+
859909
#[derive(Copy, Clone, Debug)]
860910
enum FuseState {
861911
Start,
@@ -1563,6 +1613,14 @@ mod test {
15631613
test(it, &[0, 1]);
15641614
}
15651615

1616+
#[test]
1617+
fn flat_map() {
1618+
let items = [[0, 1, 2], [3, 4, 5]];
1619+
let it = convert(items.iter()).flat_map(|i| convert(i.iter().cloned()));
1620+
1621+
test(it, &[0, 1, 2, 3, 4, 5]);
1622+
}
1623+
15661624
#[test]
15671625
fn nth() {
15681626
let items = [0, 1];

0 commit comments

Comments
 (0)