Skip to content

Commit b4cde06

Browse files
authored
Merge pull request #266 from bluss/flatten-workarounds
Add flatten() free function and fix flatten tests
2 parents aed0721 + 328fe69 commit b4cde06

File tree

5 files changed

+39
-13
lines changed

5 files changed

+39
-13
lines changed

src/adaptors/mod.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,10 +1045,31 @@ pub struct Flatten<I, J> {
10451045
front: Option<J>,
10461046
}
10471047

1048-
/// Create a new `Flatten` iterator.
1049-
pub fn flatten<I, J>(iter: I) -> Flatten<I, J> {
1048+
/// Flatten an iteratble of iterables into a single iteration of all
1049+
/// elements in the iterables.
1050+
///
1051+
/// This is more or less equivalent to `.flat_map` with an identity
1052+
/// function.
1053+
///
1054+
/// This is an `IntoIterator`-enabled version of the [`.flatten()`][1] adaptor.
1055+
///
1056+
/// [1]: trait.Itertools.html#method.flatten.
1057+
///
1058+
/// ```
1059+
/// use itertools::flatten;
1060+
///
1061+
/// let data = vec![vec![1, 2, 3], vec![4, 5, 6]];
1062+
///
1063+
/// itertools::assert_equal(flatten(&data),
1064+
/// &[1, 2, 3, 4, 5, 6]);
1065+
/// ```
1066+
pub fn flatten<I, J>(iter: I) -> Flatten<I::IntoIter, J>
1067+
where I: IntoIterator,
1068+
I::Item: IntoIterator<IntoIter=J, Item=J::Item>,
1069+
J: Iterator,
1070+
{
10501071
Flatten {
1051-
iter: iter,
1072+
iter: iter.into_iter(),
10521073
front: None,
10531074
}
10541075
}

src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ pub mod structs {
103103
pub use ziptuple::Zip;
104104
}
105105
pub use structs::*;
106+
pub use adaptors::flatten;
106107
pub use concat_impl::concat;
107108
pub use cons_tuples_impl::cons_tuples;
108109
pub use diff::diff_with;
@@ -1088,12 +1089,15 @@ pub trait Itertools : Iterator {
10881089
pad_tail::pad_using(self, min, f)
10891090
}
10901091

1091-
/// Unravel a nested iterator.
1092+
/// Flatten an iterator of iterables into a single iteration of all
1093+
/// elements in the iterables.
10921094
///
10931095
/// This is more or less equivalent to `.flat_map` with an identity
10941096
/// function.
10951097
///
1096-
/// ```
1098+
/// See also the [`flatten`](fn.flatten.html) function.
1099+
///
1100+
/// ```ignore
10971101
/// use itertools::Itertools;
10981102
///
10991103
/// let data = vec![vec![1, 2, 3], vec![4, 5, 6]];

tests/quick.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use itertools::{
1717
multizip,
1818
EitherOrBoth,
1919
};
20+
use itertools::flatten;
2021
use itertools::free::{
2122
cloned,
2223
enumerate,
@@ -604,12 +605,12 @@ quickcheck! {
604605
}
605606

606607
fn equal_flatten(a: Vec<Option<i32>>) -> bool {
607-
itertools::equal(a.iter().flatten(),
608+
itertools::equal(flatten(&a),
608609
a.iter().filter_map(|x| x.as_ref()))
609610
}
610611

611612
fn equal_flatten_vec(a: Vec<Vec<u8>>) -> bool {
612-
itertools::equal(a.iter().flatten(),
613+
itertools::equal(flatten(&a),
613614
a.iter().flat_map(|x| x))
614615
}
615616

tests/test_core.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#[macro_use] extern crate itertools as it;
99

10+
use it::flatten;
1011
use it::Itertools;
1112
use it::interleave;
1213
use it::multizip;
@@ -224,7 +225,7 @@ fn flatten_clone() {
224225
&[1,2,3],
225226
&[4,5,6]
226227
];
227-
let flattened1 = data.into_iter().cloned().flatten();
228+
let flattened1 = flatten(data.into_iter().cloned());
228229
let flattened2 = flattened1.clone();
229230

230231
it::assert_equal(flattened1, &[1,2,3,4,5,6]);

tests/test_std.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#[macro_use] extern crate itertools as it;
33
extern crate permutohedron;
44

5+
use it::flatten;
56
use it::Itertools;
67
use it::multizip;
78
use it::multipeek;
@@ -539,17 +540,15 @@ fn concat_non_empty() {
539540

540541
#[test]
541542
fn flatten_iter() {
542-
let data = vec![vec![1,2,3], vec![4,5,6]];
543-
let flattened = data.into_iter().flatten();
544-
545-
it::assert_equal(flattened, vec![1,2,3,4,5,6]);
543+
let data = vec![vec![1,2,3], vec![4,5], vec![], vec![6]];
544+
it::assert_equal(flatten(data), vec![1,2,3,4,5,6]);
546545
}
547546

548547
#[test]
549548
fn flatten_fold() {
550549
let xs = [0, 1, 1, 1, 2, 1, 3, 3];
551550
let ch = xs.iter().chunks(3);
552-
let mut iter = ch.into_iter().flatten();
551+
let mut iter = flatten(&ch);
553552
iter.next();
554553
let mut xs_d = Vec::new();
555554
iter.fold((), |(), &elt| xs_d.push(elt));

0 commit comments

Comments
 (0)