Skip to content

Commit 7d1a739

Browse files
committed
Add more multiunzip tests, fix up multiunzip doc comments
1 parent aad1260 commit 7d1a739

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,12 +3404,12 @@ pub trait Itertools : Iterator {
34043404
self.map(f).counts()
34053405
}
34063406

3407-
/// Unzips an iterator over tuples into a tuple of containers.
3407+
/// Converts an iterator of tuples into a tuple of containers.
34083408
///
3409-
/// The first element of each tuple will be put into the first container, the second element into
3410-
/// the second, ....
3409+
/// `unzip()` consumes an entire iterator of n-ary tuples, producing `n` collections, one for each
3410+
/// column.
34113411
///
3412-
/// It can be thought of as the reverse operation to [`Itertools::multiunzip`].
3412+
/// This function is, in some sense, the opposite of [`multizip`].
34133413
///
34143414
/// ```
34153415
/// use itertools::Itertools;

src/unziptuple.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
/// Unzips an iterator over tuples into a tuple of containers.
1+
/// Converts an iterator of tuples into a tuple of containers.
2+
///
3+
/// `unzip()` consumes an entire iterator of n-ary tuples, producing `n` collections, one for each
4+
/// column.
5+
///
6+
/// This function is, in some sense, the opposite of [`multizip`].
27
///
38
/// ```
49
/// use itertools::multiunzip;
@@ -9,6 +14,8 @@
914
///
1015
/// assert_eq!((a, b, c), (vec![1, 4, 7], vec![2, 5, 8], vec![3, 6, 9]));
1116
/// ```
17+
///
18+
/// [`multizip`]: crate::multizip
1219
pub fn multiunzip<FromI, I>(i: I) -> FromI
1320
where
1421
I: IntoIterator,
@@ -27,13 +34,15 @@ pub trait MultiUnzip<FromI>: Iterator {
2734

2835
macro_rules! impl_unzip_iter {
2936
($($T:ident => $FromT:ident),*) => (
30-
impl_unzip_iter!(@rec $($T => $FromT,)*);
31-
);
32-
(@rec) => ();
33-
(@rec $__:ident => $___:ident, $($T:ident => $FromT:ident,)*) => (
3437
#[allow(non_snake_case)]
3538
impl<IT: Iterator<Item = ($($T,)*)>, $($T, $FromT: Default + Extend<$T>),* > MultiUnzip<($($FromT,)*)> for IT {
3639
fn multiunzip(self) -> ($($FromT,)*) {
40+
// This implementation mirrors the logic of Iterator::unzip as close as possible.
41+
// Unfortunately a lot of the used api there is still unstable represented by
42+
// the commented out parts that follow.
43+
//
44+
// https://doc.rust-lang.org/src/core/iter/traits/iterator.rs.html#2816-2844
45+
3746
let mut res = ($($FromT::default(),)*);
3847
let ($($FromT,)*) = &mut res;
3948

@@ -51,8 +60,19 @@ macro_rules! impl_unzip_iter {
5160
res
5261
}
5362
}
54-
impl_unzip_iter!(@rec $($T => $FromT,)*);
5563
);
5664
}
5765

58-
impl_unzip_iter!(L => FromL, K => FromK, J => FromJ, I => FromI, H => FromH, G => FromG, F => FromF, E => FromE, D => FromD, C => FromC, B => FromB, A => FromA);
66+
impl_unzip_iter!();
67+
impl_unzip_iter!(A => FromA);
68+
impl_unzip_iter!(A => FromA, B => FromB);
69+
impl_unzip_iter!(A => FromA, B => FromB, C => FromC);
70+
impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD);
71+
impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE);
72+
impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF);
73+
impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG);
74+
impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG, H => FromH);
75+
impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG, H => FromH, I => FromI);
76+
impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG, H => FromH, I => FromI, J => FromJ);
77+
impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG, H => FromH, I => FromI, J => FromJ, K => FromK);
78+
impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG, H => FromH, I => FromI, J => FromJ, K => FromK, L => FromL);

tests/test_std.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,4 +1085,7 @@ fn exactly_one_question_mark_return() -> Result<(), ExactlyOneError<std::slice::
10851085
fn multiunzip() {
10861086
let (a, b, c): (Vec<_>, Vec<_>, Vec<_>) = [(0, 1, 2), (3, 4, 5), (6, 7, 8)].iter().cloned().multiunzip();
10871087
assert_eq!((a, b, c), (vec![0, 3, 6], vec![1, 4, 7], vec![2, 5, 8]));
1088+
let (): () = [(), (), ()].iter().cloned().multiunzip();
1089+
let t: (Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>) = [(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)].iter().cloned().multiunzip();
1090+
assert_eq!(t, (vec![0], vec![1], vec![2], vec![3], vec![4], vec![5], vec![6], vec![7], vec![8], vec![9], vec![10], vec![11]));
10881091
}

0 commit comments

Comments
 (0)