@@ -226,6 +226,26 @@ pub trait IteratorUtil<A> {
226
226
fn scan < ' r , St , B > ( self , initial_state : St , f : & ' r fn ( & mut St , A ) -> Option < B > )
227
227
-> ScanIterator < ' r , A , B , Self , St > ;
228
228
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
+
229
249
/// An adaptation of an external iterator to the for-loop protocol of rust.
230
250
///
231
251
/// # Example
@@ -397,6 +417,12 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
397
417
ScanIterator { iter : self , f : f, state : initial_state}
398
418
}
399
419
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
+
400
426
/// A shim implementing the `for` loop iteration protocol for iterator objects
401
427
#[ inline]
402
428
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,
873
899
}
874
900
}
875
901
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
+
876
930
/// An iterator which just modifies the contained state throughout iteration.
877
931
pub struct UnfoldrIterator < ' self , A , St > {
878
932
priv f: & ' self fn( & mut St ) -> Option < A > ,
@@ -1051,6 +1105,19 @@ mod tests {
1051
1105
assert_eq ! ( i, ys. len( ) ) ;
1052
1106
}
1053
1107
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
+
1054
1121
#[ test]
1055
1122
fn test_unfoldr( ) {
1056
1123
fn count( st: & mut uint) -> Option < uint > {
0 commit comments