@@ -12,7 +12,8 @@ use cmp::Ordering;
1212use ops:: Try ;
1313
1414use super :: { AlwaysOk , LoopState } ;
15- use super :: { Chain , Cycle , Cloned , Enumerate , Filter , FilterMap , FlatMap , Fuse } ;
15+ use super :: { Chain , Cycle , Cloned , Enumerate , Filter , FilterMap , Fuse } ;
16+ use super :: { Flatten , FlatMap , flatten_compat} ;
1617use super :: { Inspect , Map , Peekable , Scan , Skip , SkipWhile , StepBy , Take , TakeWhile , Rev } ;
1718use super :: { Zip , Sum , Product } ;
1819use super :: { ChainState , FromIterator , ZipImpl } ;
@@ -997,11 +998,15 @@ pub trait Iterator {
997998 /// an extra layer of indirection. `flat_map()` will remove this extra layer
998999 /// on its own.
9991000 ///
1001+ /// You can think of [`flat_map(f)`][flat_map] as the semantic equivalent
1002+ /// of [`map`]ping, and then [`flatten`]ing as in `map(f).flatten()`.
1003+ ///
10001004 /// Another way of thinking about `flat_map()`: [`map`]'s closure returns
10011005 /// one item for each element, and `flat_map()`'s closure returns an
10021006 /// iterator for each element.
10031007 ///
10041008 /// [`map`]: #method.map
1009+ /// [`flatten`]: #method.flatten
10051010 ///
10061011 /// # Examples
10071012 ///
@@ -1021,7 +1026,79 @@ pub trait Iterator {
10211026 fn flat_map < U , F > ( self , f : F ) -> FlatMap < Self , U , F >
10221027 where Self : Sized , U : IntoIterator , F : FnMut ( Self :: Item ) -> U ,
10231028 {
1024- FlatMap { iter : self , f : f, frontiter : None , backiter : None }
1029+ FlatMap { inner : flatten_compat ( self . map ( f) ) }
1030+ }
1031+
1032+ /// Creates an iterator that flattens nested structure.
1033+ ///
1034+ /// This is useful when you have an iterator of iterators or an iterator of
1035+ /// things that can be turned into iterators and you want to remove one
1036+ /// level of indirection.
1037+ ///
1038+ /// # Examples
1039+ ///
1040+ /// Basic usage:
1041+ ///
1042+ /// ```
1043+ /// #![feature(iterator_flatten)]
1044+ ///
1045+ /// let data = vec![vec![1, 2, 3, 4], vec![5, 6]];
1046+ /// let flattened = data.into_iter().flatten().collect::<Vec<u8>>();
1047+ /// assert_eq!(flattened, &[1, 2, 3, 4, 5, 6]);
1048+ /// ```
1049+ ///
1050+ /// Mapping and then flattening:
1051+ ///
1052+ /// ```
1053+ /// #![feature(iterator_flatten)]
1054+ ///
1055+ /// let words = ["alpha", "beta", "gamma"];
1056+ ///
1057+ /// // chars() returns an iterator
1058+ /// let merged: String = words.iter()
1059+ /// .map(|s| s.chars())
1060+ /// .flatten()
1061+ /// .collect();
1062+ /// assert_eq!(merged, "alphabetagamma");
1063+ /// ```
1064+ ///
1065+ /// You can also rewrite this in terms of [`flat_map()`] which is preferable
1066+ /// in this case since that conveys intent clearer:
1067+ ///
1068+ /// ```
1069+ /// let words = ["alpha", "beta", "gamma"];
1070+ ///
1071+ /// // chars() returns an iterator
1072+ /// let merged: String = words.iter()
1073+ /// .flat_map(|s| s.chars())
1074+ /// .collect();
1075+ /// assert_eq!(merged, "alphabetagamma");
1076+ /// ```
1077+ ///
1078+ /// Flattening once only removes one level of nesting:
1079+ ///
1080+ /// ```
1081+ /// #![feature(iterator_flatten)]
1082+ ///
1083+ /// let d3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]];
1084+ ///
1085+ /// let d2 = d3.iter().flatten().collect::<Vec<_>>();
1086+ /// assert_eq!(d2, [&[1, 2], &[3, 4], &[5, 6], &[7, 8]]);
1087+ ///
1088+ /// let d1 = d3.iter().flatten().flatten().collect::<Vec<_>>();
1089+ /// assert_eq!(d1, [&1, &2, &3, &4, &5, &6, &7, &8]);
1090+ /// ```
1091+ ///
1092+ /// Here we see that `flatten()` does not perform a "deep" flatten.
1093+ /// Instead, only one level of nesting is removed. That is, if you
1094+ /// `flatten()` a three-dimensional array the result will be
1095+ /// two-dimensional and not one-dimensional. To get a one-dimensional
1096+ /// structure, you have to `flatten()` again.
1097+ #[ inline]
1098+ #[ unstable( feature = "iterator_flatten" , issue = "48213" ) ]
1099+ fn flatten ( self ) -> Flatten < Self >
1100+ where Self : Sized , Self :: Item : IntoIterator {
1101+ Flatten { inner : flatten_compat ( self ) }
10251102 }
10261103
10271104 /// Creates an iterator which ends after the first [`None`].
0 commit comments