1use std::iter::{IntoIterator, Iterator};
5
6pub fn zip3<A, B, C>(a: A, b: B, c: C) -> Zip3Iterator<A::IntoIter, B::IntoIter, C::IntoIter>
21where
22 A: IntoIterator,
23 B: IntoIterator,
24 C: IntoIterator,
25{
26 Zip3Iterator {
27 a: a.into_iter(),
28 b: b.into_iter(),
29 c: c.into_iter(),
30 }
31}
32
33pub fn zip3_with<A, B, C, Z, F>(transform: F, a: A, b: B, c: C) -> Vec<Z>
48where
49 A: IntoIterator,
50 B: IntoIterator,
51 C: IntoIterator,
52 F: Fn(A::Item, B::Item, C::Item) -> Z,
53{
54 zip3(a, b, c).map(|(a, b, c)| transform(a, b, c)).collect()
55}
56
57pub fn zip4<A, B, C, D>(
59 a: A,
60 b: B,
61 c: C,
62 d: D,
63) -> Zip4Iterator<A::IntoIter, B::IntoIter, C::IntoIter, D::IntoIter>
64where
65 A: IntoIterator,
66 B: IntoIterator,
67 C: IntoIterator,
68 D: IntoIterator,
69{
70 Zip4Iterator {
71 a: a.into_iter(),
72 b: b.into_iter(),
73 c: c.into_iter(),
74 d: d.into_iter(),
75 }
76}
77
78pub fn zip4_with<A, B, C, D, Z, F>(transform: F, a: A, b: B, c: C, d: D) -> Vec<Z>
80where
81 A: IntoIterator,
82 B: IntoIterator,
83 C: IntoIterator,
84 D: IntoIterator,
85 F: Fn(A::Item, B::Item, C::Item, D::Item) -> Z,
86{
87 zip4(a, b, c, d)
88 .map(|(a, b, c, d)| transform(a, b, c, d))
89 .collect()
90}
91
92pub fn zip5<A, B, C, D, E>(
94 a: A,
95 b: B,
96 c: C,
97 d: D,
98 e: E,
99) -> Zip5Iterator<A::IntoIter, B::IntoIter, C::IntoIter, D::IntoIter, E::IntoIter>
100where
101 A: IntoIterator,
102 B: IntoIterator,
103 C: IntoIterator,
104 D: IntoIterator,
105 E: IntoIterator,
106{
107 Zip5Iterator {
108 a: a.into_iter(),
109 b: b.into_iter(),
110 c: c.into_iter(),
111 d: d.into_iter(),
112 e: e.into_iter(),
113 }
114}
115
116pub fn zip5_with<A, B, C, D, E, Z, F>(transform: F, a: A, b: B, c: C, d: D, e: E) -> Vec<Z>
118where
119 A: IntoIterator,
120 B: IntoIterator,
121 C: IntoIterator,
122 D: IntoIterator,
123 E: IntoIterator,
124 F: Fn(A::Item, B::Item, C::Item, D::Item, E::Item) -> Z,
125{
126 zip5(a, b, c, d, e)
127 .map(|(a, b, c, d, e)| transform(a, b, c, d, e))
128 .collect()
129}
130
131pub fn zip6<A, B, C, D, E, F>(
133 a: A,
134 b: B,
135 c: C,
136 d: D,
137 e: E,
138 f: F,
139) -> Zip6Iterator<A::IntoIter, B::IntoIter, C::IntoIter, D::IntoIter, E::IntoIter, F::IntoIter>
140where
141 A: IntoIterator,
142 B: IntoIterator,
143 C: IntoIterator,
144 D: IntoIterator,
145 E: IntoIterator,
146 F: IntoIterator,
147{
148 Zip6Iterator {
149 a: a.into_iter(),
150 b: b.into_iter(),
151 c: c.into_iter(),
152 d: d.into_iter(),
153 e: e.into_iter(),
154 f: f.into_iter(),
155 }
156}
157
158pub fn zip6_with<A, B, C, D, E, F, Z, G>(transform: G, a: A, b: B, c: C, d: D, e: E, f: F) -> Vec<Z>
160where
161 A: IntoIterator,
162 B: IntoIterator,
163 C: IntoIterator,
164 D: IntoIterator,
165 E: IntoIterator,
166 F: IntoIterator,
167 G: Fn(A::Item, B::Item, C::Item, D::Item, E::Item, F::Item) -> Z,
168{
169 zip6(a, b, c, d, e, f)
170 .map(|(a, b, c, d, e, f)| transform(a, b, c, d, e, f))
171 .collect()
172}
173
174pub fn zip7<A, B, C, D, E, F, G>(
176 a: A,
177 b: B,
178 c: C,
179 d: D,
180 e: E,
181 f: F,
182 g: G,
183) -> Zip7Iterator<
184 A::IntoIter,
185 B::IntoIter,
186 C::IntoIter,
187 D::IntoIter,
188 E::IntoIter,
189 F::IntoIter,
190 G::IntoIter,
191>
192where
193 A: IntoIterator,
194 B: IntoIterator,
195 C: IntoIterator,
196 D: IntoIterator,
197 E: IntoIterator,
198 F: IntoIterator,
199 G: IntoIterator,
200{
201 Zip7Iterator {
202 a: a.into_iter(),
203 b: b.into_iter(),
204 c: c.into_iter(),
205 d: d.into_iter(),
206 e: e.into_iter(),
207 f: f.into_iter(),
208 g: g.into_iter(),
209 }
210}
211
212pub fn zip7_with<A, B, C, D, E, F, G, Z, H>(
214 transform: H,
215 a: A,
216 b: B,
217 c: C,
218 d: D,
219 e: E,
220 f: F,
221 g: G,
222) -> Vec<Z>
223where
224 A: IntoIterator,
225 B: IntoIterator,
226 C: IntoIterator,
227 D: IntoIterator,
228 E: IntoIterator,
229 F: IntoIterator,
230 G: IntoIterator,
231 H: Fn(A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item) -> Z,
232{
233 zip7(a, b, c, d, e, f, g)
234 .map(|(a, b, c, d, e, f, g)| transform(a, b, c, d, e, f, g))
235 .collect()
236}
237
238pub fn zip8<A, B, C, D, E, F, G, H>(
240 a: A,
241 b: B,
242 c: C,
243 d: D,
244 e: E,
245 f: F,
246 g: G,
247 h: H,
248) -> Zip8Iterator<
249 A::IntoIter,
250 B::IntoIter,
251 C::IntoIter,
252 D::IntoIter,
253 E::IntoIter,
254 F::IntoIter,
255 G::IntoIter,
256 H::IntoIter,
257>
258where
259 A: IntoIterator,
260 B: IntoIterator,
261 C: IntoIterator,
262 D: IntoIterator,
263 E: IntoIterator,
264 F: IntoIterator,
265 G: IntoIterator,
266 H: IntoIterator,
267{
268 Zip8Iterator {
269 a: a.into_iter(),
270 b: b.into_iter(),
271 c: c.into_iter(),
272 d: d.into_iter(),
273 e: e.into_iter(),
274 f: f.into_iter(),
275 g: g.into_iter(),
276 h: h.into_iter(),
277 }
278}
279
280pub fn zip8_with<A, B, C, D, E, F, G, H, Z, I>(
282 transform: I,
283 a: A,
284 b: B,
285 c: C,
286 d: D,
287 e: E,
288 f: F,
289 g: G,
290 h: H,
291) -> Vec<Z>
292where
293 A: IntoIterator,
294 B: IntoIterator,
295 C: IntoIterator,
296 D: IntoIterator,
297 E: IntoIterator,
298 F: IntoIterator,
299 G: IntoIterator,
300 H: IntoIterator,
301 I: Fn(A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item, H::Item) -> Z,
302{
303 zip8(a, b, c, d, e, f, g, h)
304 .map(|(a, b, c, d, e, f, g, h)| transform(a, b, c, d, e, f, g, h))
305 .collect()
306}
307
308pub fn zip9<A, B, C, D, E, F, G, H, I>(
310 a: A,
311 b: B,
312 c: C,
313 d: D,
314 e: E,
315 f: F,
316 g: G,
317 h: H,
318 i: I,
319) -> Zip9Iterator<
320 A::IntoIter,
321 B::IntoIter,
322 C::IntoIter,
323 D::IntoIter,
324 E::IntoIter,
325 F::IntoIter,
326 G::IntoIter,
327 H::IntoIter,
328 I::IntoIter,
329>
330where
331 A: IntoIterator,
332 B: IntoIterator,
333 C: IntoIterator,
334 D: IntoIterator,
335 E: IntoIterator,
336 F: IntoIterator,
337 G: IntoIterator,
338 H: IntoIterator,
339 I: IntoIterator,
340{
341 Zip9Iterator {
342 a: a.into_iter(),
343 b: b.into_iter(),
344 c: c.into_iter(),
345 d: d.into_iter(),
346 e: e.into_iter(),
347 f: f.into_iter(),
348 g: g.into_iter(),
349 h: h.into_iter(),
350 i: i.into_iter(),
351 }
352}
353
354pub fn zip9_with<A, B, C, D, E, F, G, H, I, Z, J>(
356 transform: J,
357 a: A,
358 b: B,
359 c: C,
360 d: D,
361 e: E,
362 f: F,
363 g: G,
364 h: H,
365 i: I,
366) -> Vec<Z>
367where
368 A: IntoIterator,
369 B: IntoIterator,
370 C: IntoIterator,
371 D: IntoIterator,
372 E: IntoIterator,
373 F: IntoIterator,
374 G: IntoIterator,
375 H: IntoIterator,
376 I: IntoIterator,
377 J: Fn(A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item, H::Item, I::Item) -> Z,
378{
379 zip9(a, b, c, d, e, f, g, h, i)
380 .map(|(a, b, c, d, e, f, g, h, i)| transform(a, b, c, d, e, f, g, h, i))
381 .collect()
382}
383
384pub fn zip10<A, B, C, D, E, F, G, H, I, J>(
386 a: A,
387 b: B,
388 c: C,
389 d: D,
390 e: E,
391 f: F,
392 g: G,
393 h: H,
394 i: I,
395 j: J,
396) -> Zip10Iterator<
397 A::IntoIter,
398 B::IntoIter,
399 C::IntoIter,
400 D::IntoIter,
401 E::IntoIter,
402 F::IntoIter,
403 G::IntoIter,
404 H::IntoIter,
405 I::IntoIter,
406 J::IntoIter,
407>
408where
409 A: IntoIterator,
410 B: IntoIterator,
411 C: IntoIterator,
412 D: IntoIterator,
413 E: IntoIterator,
414 F: IntoIterator,
415 G: IntoIterator,
416 H: IntoIterator,
417 I: IntoIterator,
418 J: IntoIterator,
419{
420 Zip10Iterator {
421 a: a.into_iter(),
422 b: b.into_iter(),
423 c: c.into_iter(),
424 d: d.into_iter(),
425 e: e.into_iter(),
426 f: f.into_iter(),
427 g: g.into_iter(),
428 h: h.into_iter(),
429 i: i.into_iter(),
430 j: j.into_iter(),
431 }
432}
433
434pub fn zip10_with<A, B, C, D, E, F, G, H, I, J, Z, K>(
436 transform: K,
437 a: A,
438 b: B,
439 c: C,
440 d: D,
441 e: E,
442 f: F,
443 g: G,
444 h: H,
445 i: I,
446 j: J,
447) -> Vec<Z>
448where
449 A: IntoIterator,
450 B: IntoIterator,
451 C: IntoIterator,
452 D: IntoIterator,
453 E: IntoIterator,
454 F: IntoIterator,
455 G: IntoIterator,
456 H: IntoIterator,
457 I: IntoIterator,
458 J: IntoIterator,
459 K: Fn(
460 A::Item,
461 B::Item,
462 C::Item,
463 D::Item,
464 E::Item,
465 F::Item,
466 G::Item,
467 H::Item,
468 I::Item,
469 J::Item,
470 ) -> Z,
471{
472 zip10(a, b, c, d, e, f, g, h, i, j)
473 .map(|(a, b, c, d, e, f, g, h, i, j)| transform(a, b, c, d, e, f, g, h, i, j))
474 .collect()
475}
476
477pub struct Zip3Iterator<A, B, C> {
481 a: A,
482 b: B,
483 c: C,
484}
485
486impl<A, B, C> Iterator for Zip3Iterator<A, B, C>
487where
488 A: Iterator,
489 B: Iterator,
490 C: Iterator,
491{
492 type Item = (A::Item, B::Item, C::Item);
493
494 fn next(&mut self) -> Option<Self::Item> {
495 match (self.a.next(), self.b.next(), self.c.next()) {
496 (Some(a), Some(b), Some(c)) => Some((a, b, c)),
497 _ => None,
498 }
499 }
500}
501
502pub struct Zip4Iterator<A, B, C, D> {
504 a: A,
505 b: B,
506 c: C,
507 d: D,
508}
509
510impl<A, B, C, D> Iterator for Zip4Iterator<A, B, C, D>
511where
512 A: Iterator,
513 B: Iterator,
514 C: Iterator,
515 D: Iterator,
516{
517 type Item = (A::Item, B::Item, C::Item, D::Item);
518
519 fn next(&mut self) -> Option<Self::Item> {
520 match (self.a.next(), self.b.next(), self.c.next(), self.d.next()) {
521 (Some(a), Some(b), Some(c), Some(d)) => Some((a, b, c, d)),
522 _ => None,
523 }
524 }
525}
526
527pub struct Zip5Iterator<A, B, C, D, E> {
529 a: A,
530 b: B,
531 c: C,
532 d: D,
533 e: E,
534}
535
536impl<A, B, C, D, E> Iterator for Zip5Iterator<A, B, C, D, E>
537where
538 A: Iterator,
539 B: Iterator,
540 C: Iterator,
541 D: Iterator,
542 E: Iterator,
543{
544 type Item = (A::Item, B::Item, C::Item, D::Item, E::Item);
545
546 fn next(&mut self) -> Option<Self::Item> {
547 match (
548 self.a.next(),
549 self.b.next(),
550 self.c.next(),
551 self.d.next(),
552 self.e.next(),
553 ) {
554 (Some(a), Some(b), Some(c), Some(d), Some(e)) => Some((a, b, c, d, e)),
555 _ => None,
556 }
557 }
558}
559
560pub struct Zip6Iterator<A, B, C, D, E, F> {
562 a: A,
563 b: B,
564 c: C,
565 d: D,
566 e: E,
567 f: F,
568}
569
570impl<A, B, C, D, E, F> Iterator for Zip6Iterator<A, B, C, D, E, F>
571where
572 A: Iterator,
573 B: Iterator,
574 C: Iterator,
575 D: Iterator,
576 E: Iterator,
577 F: Iterator,
578{
579 type Item = (A::Item, B::Item, C::Item, D::Item, E::Item, F::Item);
580
581 fn next(&mut self) -> Option<Self::Item> {
582 match (
583 self.a.next(),
584 self.b.next(),
585 self.c.next(),
586 self.d.next(),
587 self.e.next(),
588 self.f.next(),
589 ) {
590 (Some(a), Some(b), Some(c), Some(d), Some(e), Some(f)) => Some((a, b, c, d, e, f)),
591 _ => None,
592 }
593 }
594}
595
596pub struct Zip7Iterator<A, B, C, D, E, F, G> {
598 a: A,
599 b: B,
600 c: C,
601 d: D,
602 e: E,
603 f: F,
604 g: G,
605}
606
607impl<A, B, C, D, E, F, G> Iterator for Zip7Iterator<A, B, C, D, E, F, G>
608where
609 A: Iterator,
610 B: Iterator,
611 C: Iterator,
612 D: Iterator,
613 E: Iterator,
614 F: Iterator,
615 G: Iterator,
616{
617 type Item = (
618 A::Item,
619 B::Item,
620 C::Item,
621 D::Item,
622 E::Item,
623 F::Item,
624 G::Item,
625 );
626
627 fn next(&mut self) -> Option<Self::Item> {
628 match (
629 self.a.next(),
630 self.b.next(),
631 self.c.next(),
632 self.d.next(),
633 self.e.next(),
634 self.f.next(),
635 self.g.next(),
636 ) {
637 (Some(a), Some(b), Some(c), Some(d), Some(e), Some(f), Some(g)) => {
638 Some((a, b, c, d, e, f, g))
639 }
640 _ => None,
641 }
642 }
643}
644
645pub struct Zip8Iterator<A, B, C, D, E, F, G, H> {
647 a: A,
648 b: B,
649 c: C,
650 d: D,
651 e: E,
652 f: F,
653 g: G,
654 h: H,
655}
656
657impl<A, B, C, D, E, F, G, H> Iterator for Zip8Iterator<A, B, C, D, E, F, G, H>
658where
659 A: Iterator,
660 B: Iterator,
661 C: Iterator,
662 D: Iterator,
663 E: Iterator,
664 F: Iterator,
665 G: Iterator,
666 H: Iterator,
667{
668 type Item = (
669 A::Item,
670 B::Item,
671 C::Item,
672 D::Item,
673 E::Item,
674 F::Item,
675 G::Item,
676 H::Item,
677 );
678
679 fn next(&mut self) -> Option<Self::Item> {
680 match (
681 self.a.next(),
682 self.b.next(),
683 self.c.next(),
684 self.d.next(),
685 self.e.next(),
686 self.f.next(),
687 self.g.next(),
688 self.h.next(),
689 ) {
690 (Some(a), Some(b), Some(c), Some(d), Some(e), Some(f), Some(g), Some(h)) => {
691 Some((a, b, c, d, e, f, g, h))
692 }
693 _ => None,
694 }
695 }
696}
697
698pub struct Zip9Iterator<A, B, C, D, E, F, G, H, I> {
700 a: A,
701 b: B,
702 c: C,
703 d: D,
704 e: E,
705 f: F,
706 g: G,
707 h: H,
708 i: I,
709}
710
711impl<A, B, C, D, E, F, G, H, I> Iterator for Zip9Iterator<A, B, C, D, E, F, G, H, I>
712where
713 A: Iterator,
714 B: Iterator,
715 C: Iterator,
716 D: Iterator,
717 E: Iterator,
718 F: Iterator,
719 G: Iterator,
720 H: Iterator,
721 I: Iterator,
722{
723 type Item = (
724 A::Item,
725 B::Item,
726 C::Item,
727 D::Item,
728 E::Item,
729 F::Item,
730 G::Item,
731 H::Item,
732 I::Item,
733 );
734
735 fn next(&mut self) -> Option<Self::Item> {
736 match (
737 self.a.next(),
738 self.b.next(),
739 self.c.next(),
740 self.d.next(),
741 self.e.next(),
742 self.f.next(),
743 self.g.next(),
744 self.h.next(),
745 self.i.next(),
746 ) {
747 (Some(a), Some(b), Some(c), Some(d), Some(e), Some(f), Some(g), Some(h), Some(i)) => {
748 Some((a, b, c, d, e, f, g, h, i))
749 }
750 _ => None,
751 }
752 }
753}
754
755pub struct Zip10Iterator<A, B, C, D, E, F, G, H, I, J> {
757 a: A,
758 b: B,
759 c: C,
760 d: D,
761 e: E,
762 f: F,
763 g: G,
764 h: H,
765 i: I,
766 j: J,
767}
768
769impl<A, B, C, D, E, F, G, H, I, J> Iterator for Zip10Iterator<A, B, C, D, E, F, G, H, I, J>
770where
771 A: Iterator,
772 B: Iterator,
773 C: Iterator,
774 D: Iterator,
775 E: Iterator,
776 F: Iterator,
777 G: Iterator,
778 H: Iterator,
779 I: Iterator,
780 J: Iterator,
781{
782 type Item = (
783 A::Item,
784 B::Item,
785 C::Item,
786 D::Item,
787 E::Item,
788 F::Item,
789 G::Item,
790 H::Item,
791 I::Item,
792 J::Item,
793 );
794
795 fn next(&mut self) -> Option<Self::Item> {
796 match (
797 self.a.next(),
798 self.b.next(),
799 self.c.next(),
800 self.d.next(),
801 self.e.next(),
802 self.f.next(),
803 self.g.next(),
804 self.h.next(),
805 self.i.next(),
806 self.j.next(),
807 ) {
808 (
809 Some(a),
810 Some(b),
811 Some(c),
812 Some(d),
813 Some(e),
814 Some(f),
815 Some(g),
816 Some(h),
817 Some(i),
818 Some(j),
819 ) => Some((a, b, c, d, e, f, g, h, i, j)),
820 _ => None,
821 }
822 }
823}
824
825#[cfg(test)]
826mod tests {
827 use super::*;
828
829 #[test]
830 fn test_zip3() {
831 let a = vec![1, 2, 3];
832 let b = vec![4, 5, 6];
833 let c = vec![7, 8, 9];
834
835 let zipped: Vec<_> = zip3(a, b, c).collect();
836 assert_eq!(zipped, vec![(1, 4, 7), (2, 5, 8), (3, 6, 9)]);
837 }
838
839 #[test]
840 fn test_zip3_with() {
841 let a = vec![1, 2, 3];
842 let b = vec![4, 5, 6];
843 let c = vec![7, 8, 9];
844
845 let result = zip3_with(|x, y, z| x + y + z, a, b, c);
846 assert_eq!(result, vec![12, 15, 18]);
847 }
848
849 #[test]
850 fn test_zip4() {
851 let a = vec![1, 2, 3];
852 let b = vec![4, 5, 6];
853 let c = vec![7, 8, 9];
854 let d = vec![10, 11, 12];
855
856 let zipped: Vec<_> = zip4(a, b, c, d).collect();
857 assert_eq!(zipped, vec![(1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)]);
858 }
859
860 #[test]
861 fn test_zip4_with() {
862 let a = vec![1, 2, 3];
863 let b = vec![4, 5, 6];
864 let c = vec![7, 8, 9];
865 let d = vec![10, 11, 12];
866
867 let result = zip4_with(|w, x, y, z| w + x + y + z, a, b, c, d);
868 assert_eq!(result, vec![22, 26, 30]);
869 }
870
871 #[test]
872 fn test_zip5() {
873 let a = vec![1, 2, 3];
874 let b = vec![4, 5, 6];
875 let c = vec![7, 8, 9];
876 let d = vec![10, 11, 12];
877 let e = vec![13, 14, 15];
878
879 let zipped: Vec<_> = zip5(a, b, c, d, e).collect();
880 assert_eq!(
881 zipped,
882 vec![(1, 4, 7, 10, 13), (2, 5, 8, 11, 14), (3, 6, 9, 12, 15)]
883 );
884 }
885
886 #[test]
887 fn test_zip5_with() {
888 let a = vec![1, 2, 3];
889 let b = vec![4, 5, 6];
890 let c = vec![7, 8, 9];
891 let d = vec![10, 11, 12];
892 let e = vec![13, 14, 15];
893
894 let result = zip5_with(|v, w, x, y, z| v + w + x + y + z, a, b, c, d, e);
895 assert_eq!(result, vec![35, 40, 45]);
896 }
897
898 #[test]
899 fn test_zip_different_lengths() {
900 let a = vec![1, 2, 3, 4];
901 let b = vec![5, 6];
902 let c = vec![7, 8, 9];
903
904 let zipped: Vec<_> = zip3(a, b, c).collect();
905 assert_eq!(zipped, vec![(1, 5, 7), (2, 6, 8)]);
906 }
907
908 #[test]
909 fn test_zip_with_strings() {
910 let names = vec!["Alice", "Bob", "Charlie"];
911 let ages = vec![25, 30, 35];
912 let cities = vec!["New York", "London", "Tokyo"];
913
914 let result = zip3_with(
915 |name, age, city| format!("{} is {} years old and lives in {}", name, age, city),
916 names,
917 ages,
918 cities,
919 );
920 assert_eq!(
921 result,
922 vec![
923 "Alice is 25 years old and lives in New York",
924 "Bob is 30 years old and lives in London",
925 "Charlie is 35 years old and lives in Tokyo"
926 ]
927 );
928 }
929}