@@ -226,6 +226,26 @@ pub trait IteratorUtil<A> {
226226 fn scan < ' r , St , B > ( self , initial_state : St , f : & ' r fn ( & mut St , A ) -> Option < B > )
227227 -> ScanIterator < ' r , A , B , Self , St > ;
228228
229+ /// Creates an iterator that maps each element to an iterator,
230+ /// and yields the elements of the produced iterators
231+ ///
232+ /// # Example
233+ ///
234+ /// ~~~ {.rust}
235+ /// let xs = [2u, 3];
236+ /// let ys = [0u, 1, 0, 1, 2];
237+ /// let mut it = xs.iter().flat_map_(|&x| Counter::new(0u, 1).take_(x));
238+ /// // Check that `it` has the same elements as `ys`
239+ /// let mut i = 0;
240+ /// for it.advance |x: uint| {
241+ /// assert_eq!(x, ys[i]);
242+ /// i += 1;
243+ /// }
244+ /// ~~~
245+ // FIXME: #5898: should be called `flat_map`
246+ fn flat_map_ < ' r , B , U : Iterator < B > > ( self , f : & ' r fn ( A ) -> U )
247+ -> FlatMapIterator < ' r , A , B , Self , U > ;
248+
229249 /// An adaptation of an external iterator to the for-loop protocol of rust.
230250 ///
231251 /// # Example
@@ -397,6 +417,12 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
397417 ScanIterator { iter : self , f : f, state : initial_state}
398418 }
399419
420+ #[ inline]
421+ fn flat_map_ < ' r , B , U : Iterator < B > > ( self , f : & ' r fn ( A ) -> U )
422+ -> FlatMapIterator < ' r , A , B , T , U > {
423+ FlatMapIterator { iter : self , f : f, subiter : None }
424+ }
425+
400426 /// A shim implementing the `for` loop iteration protocol for iterator objects
401427 #[ inline]
402428 fn advance ( & mut self , f : & fn ( A ) -> bool ) -> bool {
@@ -873,6 +899,34 @@ impl<'self, A, B, T: Iterator<A>, St> Iterator<B> for ScanIterator<'self, A, B,
873899 }
874900}
875901
902+ /// An iterator that maps each element to an iterator,
903+ /// and yields the elements of the produced iterators
904+ ///
905+ // FIXME #6967: Dummy B parameter to get around type inference bug
906+ pub struct FlatMapIterator < ' self , A , B , T , U > {
907+ priv iter: T ,
908+ priv f: & ' self fn ( A ) -> U ,
909+ priv subiter: Option < U > ,
910+ }
911+
912+ impl <' self , A , T : Iterator < A > , B , U : Iterator < B > > Iterator < B > for
913+ FlatMapIterator < ' self , A , B , T , U > {
914+ #[ inline]
915+ fn next( & mut self ) -> Option < B > {
916+ loop {
917+ for self . subiter. mut_iter( ) . advance |inner| {
918+ for inner. advance |x| {
919+ return Some ( x)
920+ }
921+ }
922+ match self . iter. next( ) . map_consume( self . f) {
923+ None => return None ,
924+ next => self . subiter = next,
925+ }
926+ }
927+ }
928+ }
929+
876930/// An iterator which just modifies the contained state throughout iteration.
877931pub struct UnfoldrIterator < ' self , A , St > {
878932 priv f: & ' self fn( & mut St ) -> Option < A > ,
@@ -1051,6 +1105,19 @@ mod tests {
10511105 assert_eq ! ( i, ys. len( ) ) ;
10521106 }
10531107
1108+ #[ test]
1109+ fn test_iterator_flat_map( ) {
1110+ let xs = [ 0 u, 3 , 6 ] ;
1111+ let ys = [ 0 u, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ;
1112+ let mut it = xs. iter( ) . flat_map_( |& x| Counter :: new( x, 1 ) . take_( 3 ) ) ;
1113+ let mut i = 0 ;
1114+ for it. advance |x: uint| {
1115+ assert_eq ! ( x, ys[ i] ) ;
1116+ i += 1 ;
1117+ }
1118+ assert_eq ! ( i, ys. len( ) ) ;
1119+ }
1120+
10541121 #[ test]
10551122 fn test_unfoldr( ) {
10561123 fn count( st: & mut uint) -> Option < uint > {
0 commit comments