3 /// See [`multizip`](../fn.multizip.html) for more information.
4 #[derive(Clone, Debug)]
5 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
10 /// An iterator that generalizes *.zip()* and allows running multiple iterators in lockstep.
12 /// The iterator `Zip<(I, J, ..., M)>` is formed from a tuple of iterators (or values that
13 /// implement `IntoIterator`) and yields elements
14 /// until any of the subiterators yields `None`.
16 /// The iterator element type is a tuple like like `(A, B, ..., E)` where `A` to `E` are the
17 /// element types of the subiterator.
19 /// **Note:** The result of this macro is a value of a named type (`Zip<(I, J,
20 /// ..)>` of each component iterator `I, J, ...`) if each component iterator is
23 /// Prefer [`izip!()`] over `multizip` for the performance benefits of using the
24 /// standard library `.zip()`. Prefer `multizip` if a nameable type is needed.
26 /// [`izip!()`]: macro.izip.html
29 /// use itertools::multizip;
31 /// // iterate over three sequences side-by-side
32 /// let mut results = [0, 0, 0, 0];
33 /// let inputs = [3, 7, 9, 6];
35 /// for (r, index, input) in multizip((&mut results, 0..10, &inputs)) {
36 /// *r = index * 10 + input;
39 /// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
41 pub fn multizip
<T
, U
>(t
: U
) -> Zip
<T
>
42 where Zip
<T
>: From
<U
>,
48 macro_rules
! impl_zip_iter
{
50 #[allow(non_snake_case)]
51 impl<$
($B
: IntoIterator
),*> From
<($
($B
,)*)> for Zip
<($
($B
::IntoIter
,)*)> {
52 fn from(t
: ($
($B
,)*)) -> Self {
54 Zip { t: ($($B.into_iter(),)*) }
58 #[allow(non_snake_case)]
59 #[allow(unused_assignments)]
60 impl<$
($B
),*> Iterator
for Zip
<($
($B
,)*)>
66 type Item
= ($
($B
::Item
,)*);
68 fn next(&mut self) -> Option
<Self::Item
>
70 let ($
(ref mut $B
,)*) = self.t
;
72 // NOTE: Just like iter::Zip, we check the iterators
73 // for None in order. We may finish unevenly (some
74 // iterators gave n + 1 elements, some only n).
76 let $B
= match $B
.next() {
84 fn size_hint(&self) -> (usize, Option
<usize>)
86 let sh
= (::std
::usize::MAX
, None
);
87 let ($
(ref $B
,)*) = self.t
;
89 let sh
= size_hint
::min($B
.size_hint(), sh
);
95 #[allow(non_snake_case)]
96 impl<$
($B
),*> ExactSizeIterator
for Zip
<($
($B
,)*)> where
98 $B
: ExactSizeIterator
,
105 impl_zip_iter
!(A
, B
);
106 impl_zip_iter
!(A
, B
, C
);
107 impl_zip_iter
!(A
, B
, C
, D
);
108 impl_zip_iter
!(A
, B
, C
, D
, E
);
109 impl_zip_iter
!(A
, B
, C
, D
, E
, F
);
110 impl_zip_iter
!(A
, B
, C
, D
, E
, F
, G
);
111 impl_zip_iter
!(A
, B
, C
, D
, E
, F
, G
, H
);