1use std::iter::{Iterator, IntoIterator};
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>(a: A, b: B, c: C, d: D) -> Zip4Iterator<A::IntoIter, B::IntoIter, C::IntoIter, D::IntoIter>
59where
60 A: IntoIterator,
61 B: IntoIterator,
62 C: IntoIterator,
63 D: IntoIterator,
64{
65 Zip4Iterator {
66 a: a.into_iter(),
67 b: b.into_iter(),
68 c: c.into_iter(),
69 d: d.into_iter(),
70 }
71}
72
73pub fn zip4_with<A, B, C, D, Z, F>(transform: F, a: A, b: B, c: C, d: D) -> Vec<Z>
75where
76 A: IntoIterator,
77 B: IntoIterator,
78 C: IntoIterator,
79 D: IntoIterator,
80 F: Fn(A::Item, B::Item, C::Item, D::Item) -> Z,
81{
82 zip4(a, b, c, d).map(|(a, b, c, d)| transform(a, b, c, d)).collect()
83}
84
85pub fn zip5<A, B, C, D, E>(a: A, b: B, c: C, d: D, e: E) -> Zip5Iterator<A::IntoIter, B::IntoIter, C::IntoIter, D::IntoIter, E::IntoIter>
87where
88 A: IntoIterator,
89 B: IntoIterator,
90 C: IntoIterator,
91 D: IntoIterator,
92 E: IntoIterator,
93{
94 Zip5Iterator {
95 a: a.into_iter(),
96 b: b.into_iter(),
97 c: c.into_iter(),
98 d: d.into_iter(),
99 e: e.into_iter(),
100 }
101}
102
103pub fn zip5_with<A, B, C, D, E, Z, F>(transform: F, a: A, b: B, c: C, d: D, e: E) -> Vec<Z>
105where
106 A: IntoIterator,
107 B: IntoIterator,
108 C: IntoIterator,
109 D: IntoIterator,
110 E: IntoIterator,
111 F: Fn(A::Item, B::Item, C::Item, D::Item, E::Item) -> Z,
112{
113 zip5(a, b, c, d, e).map(|(a, b, c, d, e)| transform(a, b, c, d, e)).collect()
114}
115
116pub fn zip6<A, B, C, D, E, F>(a: A, b: B, c: C, d: D, e: E, f: F) -> Zip6Iterator<A::IntoIter, B::IntoIter, C::IntoIter, D::IntoIter, E::IntoIter, F::IntoIter>
118where
119 A: IntoIterator,
120 B: IntoIterator,
121 C: IntoIterator,
122 D: IntoIterator,
123 E: IntoIterator,
124 F: IntoIterator,
125{
126 Zip6Iterator {
127 a: a.into_iter(),
128 b: b.into_iter(),
129 c: c.into_iter(),
130 d: d.into_iter(),
131 e: e.into_iter(),
132 f: f.into_iter(),
133 }
134}
135
136pub 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>
138where
139 A: IntoIterator,
140 B: IntoIterator,
141 C: IntoIterator,
142 D: IntoIterator,
143 E: IntoIterator,
144 F: IntoIterator,
145 G: Fn(A::Item, B::Item, C::Item, D::Item, E::Item, F::Item) -> Z,
146{
147 zip6(a, b, c, d, e, f).map(|(a, b, c, d, e, f)| transform(a, b, c, d, e, f)).collect()
148}
149
150pub fn zip7<A, B, C, D, E, F, G>(a: A, b: B, c: C, d: D, e: E, f: F, g: G) -> Zip7Iterator<A::IntoIter, B::IntoIter, C::IntoIter, D::IntoIter, E::IntoIter, F::IntoIter, G::IntoIter>
152where
153 A: IntoIterator,
154 B: IntoIterator,
155 C: IntoIterator,
156 D: IntoIterator,
157 E: IntoIterator,
158 F: IntoIterator,
159 G: IntoIterator,
160{
161 Zip7Iterator {
162 a: a.into_iter(),
163 b: b.into_iter(),
164 c: c.into_iter(),
165 d: d.into_iter(),
166 e: e.into_iter(),
167 f: f.into_iter(),
168 g: g.into_iter(),
169 }
170}
171
172pub fn zip7_with<A, B, C, D, E, F, G, Z, H>(transform: H, a: A, b: B, c: C, d: D, e: E, f: F, g: G) -> Vec<Z>
174where
175 A: IntoIterator,
176 B: IntoIterator,
177 C: IntoIterator,
178 D: IntoIterator,
179 E: IntoIterator,
180 F: IntoIterator,
181 G: IntoIterator,
182 H: Fn(A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item) -> Z,
183{
184 zip7(a, b, c, d, e, f, g).map(|(a, b, c, d, e, f, g)| transform(a, b, c, d, e, f, g)).collect()
185}
186
187pub fn zip8<A, B, C, D, E, F, G, H>(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) -> Zip8Iterator<A::IntoIter, B::IntoIter, C::IntoIter, D::IntoIter, E::IntoIter, F::IntoIter, G::IntoIter, H::IntoIter>
189where
190 A: IntoIterator,
191 B: IntoIterator,
192 C: IntoIterator,
193 D: IntoIterator,
194 E: IntoIterator,
195 F: IntoIterator,
196 G: IntoIterator,
197 H: IntoIterator,
198{
199 Zip8Iterator {
200 a: a.into_iter(),
201 b: b.into_iter(),
202 c: c.into_iter(),
203 d: d.into_iter(),
204 e: e.into_iter(),
205 f: f.into_iter(),
206 g: g.into_iter(),
207 h: h.into_iter(),
208 }
209}
210
211pub fn zip8_with<A, B, C, D, E, F, G, H, Z, I>(transform: I, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) -> Vec<Z>
213where
214 A: IntoIterator,
215 B: IntoIterator,
216 C: IntoIterator,
217 D: IntoIterator,
218 E: IntoIterator,
219 F: IntoIterator,
220 G: IntoIterator,
221 H: IntoIterator,
222 I: Fn(A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item, H::Item) -> Z,
223{
224 zip8(a, b, c, d, e, f, g, h).map(|(a, b, c, d, e, f, g, h)| transform(a, b, c, d, e, f, g, h)).collect()
225}
226
227pub fn zip9<A, B, C, D, E, F, G, H, I>(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) -> Zip9Iterator<A::IntoIter, B::IntoIter, C::IntoIter, D::IntoIter, E::IntoIter, F::IntoIter, G::IntoIter, H::IntoIter, I::IntoIter>
229where
230 A: IntoIterator,
231 B: IntoIterator,
232 C: IntoIterator,
233 D: IntoIterator,
234 E: IntoIterator,
235 F: IntoIterator,
236 G: IntoIterator,
237 H: IntoIterator,
238 I: IntoIterator,
239{
240 Zip9Iterator {
241 a: a.into_iter(),
242 b: b.into_iter(),
243 c: c.into_iter(),
244 d: d.into_iter(),
245 e: e.into_iter(),
246 f: f.into_iter(),
247 g: g.into_iter(),
248 h: h.into_iter(),
249 i: i.into_iter(),
250 }
251}
252
253pub fn zip9_with<A, B, C, D, E, F, G, H, I, Z, J>(transform: J, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) -> Vec<Z>
255where
256 A: IntoIterator,
257 B: IntoIterator,
258 C: IntoIterator,
259 D: IntoIterator,
260 E: IntoIterator,
261 F: IntoIterator,
262 G: IntoIterator,
263 H: IntoIterator,
264 I: IntoIterator,
265 J: Fn(A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item, H::Item, I::Item) -> Z,
266{
267 zip9(a, b, c, d, e, f, g, h, i).map(|(a, b, c, d, e, f, g, h, i)| transform(a, b, c, d, e, f, g, h, i)).collect()
268}
269
270pub fn zip10<A, B, C, D, E, F, G, H, I, J>(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) -> Zip10Iterator<A::IntoIter, B::IntoIter, C::IntoIter, D::IntoIter, E::IntoIter, F::IntoIter, G::IntoIter, H::IntoIter, I::IntoIter, J::IntoIter>
272where
273 A: IntoIterator,
274 B: IntoIterator,
275 C: IntoIterator,
276 D: IntoIterator,
277 E: IntoIterator,
278 F: IntoIterator,
279 G: IntoIterator,
280 H: IntoIterator,
281 I: IntoIterator,
282 J: IntoIterator,
283{
284 Zip10Iterator {
285 a: a.into_iter(),
286 b: b.into_iter(),
287 c: c.into_iter(),
288 d: d.into_iter(),
289 e: e.into_iter(),
290 f: f.into_iter(),
291 g: g.into_iter(),
292 h: h.into_iter(),
293 i: i.into_iter(),
294 j: j.into_iter(),
295 }
296}
297
298pub fn zip10_with<A, B, C, D, E, F, G, H, I, J, Z, K>(transform: K, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) -> Vec<Z>
300where
301 A: IntoIterator,
302 B: IntoIterator,
303 C: IntoIterator,
304 D: IntoIterator,
305 E: IntoIterator,
306 F: IntoIterator,
307 G: IntoIterator,
308 H: IntoIterator,
309 I: IntoIterator,
310 J: IntoIterator,
311 K: Fn(A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item, H::Item, I::Item, J::Item) -> Z,
312{
313 zip10(a, b, c, d, e, f, g, h, i, j).map(|(a, b, c, d, e, f, g, h, i, j)| transform(a, b, c, d, e, f, g, h, i, j)).collect()
314}
315
316pub struct Zip3Iterator<A, B, C> {
320 a: A,
321 b: B,
322 c: C,
323}
324
325impl<A, B, C> Iterator for Zip3Iterator<A, B, C>
326where
327 A: Iterator,
328 B: Iterator,
329 C: Iterator,
330{
331 type Item = (A::Item, B::Item, C::Item);
332
333 fn next(&mut self) -> Option<Self::Item> {
334 match (self.a.next(), self.b.next(), self.c.next()) {
335 (Some(a), Some(b), Some(c)) => Some((a, b, c)),
336 _ => None,
337 }
338 }
339}
340
341pub struct Zip4Iterator<A, B, C, D> {
343 a: A,
344 b: B,
345 c: C,
346 d: D,
347}
348
349impl<A, B, C, D> Iterator for Zip4Iterator<A, B, C, D>
350where
351 A: Iterator,
352 B: Iterator,
353 C: Iterator,
354 D: Iterator,
355{
356 type Item = (A::Item, B::Item, C::Item, D::Item);
357
358 fn next(&mut self) -> Option<Self::Item> {
359 match (self.a.next(), self.b.next(), self.c.next(), self.d.next()) {
360 (Some(a), Some(b), Some(c), Some(d)) => Some((a, b, c, d)),
361 _ => None,
362 }
363 }
364}
365
366pub struct Zip5Iterator<A, B, C, D, E> {
368 a: A,
369 b: B,
370 c: C,
371 d: D,
372 e: E,
373}
374
375impl<A, B, C, D, E> Iterator for Zip5Iterator<A, B, C, D, E>
376where
377 A: Iterator,
378 B: Iterator,
379 C: Iterator,
380 D: Iterator,
381 E: Iterator,
382{
383 type Item = (A::Item, B::Item, C::Item, D::Item, E::Item);
384
385 fn next(&mut self) -> Option<Self::Item> {
386 match (self.a.next(), self.b.next(), self.c.next(), self.d.next(), self.e.next()) {
387 (Some(a), Some(b), Some(c), Some(d), Some(e)) => Some((a, b, c, d, e)),
388 _ => None,
389 }
390 }
391}
392
393pub struct Zip6Iterator<A, B, C, D, E, F> {
395 a: A,
396 b: B,
397 c: C,
398 d: D,
399 e: E,
400 f: F,
401}
402
403impl<A, B, C, D, E, F> Iterator for Zip6Iterator<A, B, C, D, E, F>
404where
405 A: Iterator,
406 B: Iterator,
407 C: Iterator,
408 D: Iterator,
409 E: Iterator,
410 F: Iterator,
411{
412 type Item = (A::Item, B::Item, C::Item, D::Item, E::Item, F::Item);
413
414 fn next(&mut self) -> Option<Self::Item> {
415 match (self.a.next(), self.b.next(), self.c.next(), self.d.next(), self.e.next(), self.f.next()) {
416 (Some(a), Some(b), Some(c), Some(d), Some(e), Some(f)) => Some((a, b, c, d, e, f)),
417 _ => None,
418 }
419 }
420}
421
422pub struct Zip7Iterator<A, B, C, D, E, F, G> {
424 a: A,
425 b: B,
426 c: C,
427 d: D,
428 e: E,
429 f: F,
430 g: G,
431}
432
433impl<A, B, C, D, E, F, G> Iterator for Zip7Iterator<A, B, C, D, E, F, G>
434where
435 A: Iterator,
436 B: Iterator,
437 C: Iterator,
438 D: Iterator,
439 E: Iterator,
440 F: Iterator,
441 G: Iterator,
442{
443 type Item = (A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item);
444
445 fn next(&mut self) -> Option<Self::Item> {
446 match (self.a.next(), self.b.next(), self.c.next(), self.d.next(), self.e.next(), self.f.next(), self.g.next()) {
447 (Some(a), Some(b), Some(c), Some(d), Some(e), Some(f), Some(g)) => Some((a, b, c, d, e, f, g)),
448 _ => None,
449 }
450 }
451}
452
453pub struct Zip8Iterator<A, B, C, D, E, F, G, H> {
455 a: A,
456 b: B,
457 c: C,
458 d: D,
459 e: E,
460 f: F,
461 g: G,
462 h: H,
463}
464
465impl<A, B, C, D, E, F, G, H> Iterator for Zip8Iterator<A, B, C, D, E, F, G, H>
466where
467 A: Iterator,
468 B: Iterator,
469 C: Iterator,
470 D: Iterator,
471 E: Iterator,
472 F: Iterator,
473 G: Iterator,
474 H: Iterator,
475{
476 type Item = (A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item, H::Item);
477
478 fn next(&mut self) -> Option<Self::Item> {
479 match (self.a.next(), self.b.next(), self.c.next(), self.d.next(), self.e.next(), self.f.next(), self.g.next(), self.h.next()) {
480 (Some(a), Some(b), Some(c), Some(d), Some(e), Some(f), Some(g), Some(h)) => Some((a, b, c, d, e, f, g, h)),
481 _ => None,
482 }
483 }
484}
485
486pub struct Zip9Iterator<A, B, C, D, E, F, G, H, I> {
488 a: A,
489 b: B,
490 c: C,
491 d: D,
492 e: E,
493 f: F,
494 g: G,
495 h: H,
496 i: I,
497}
498
499impl<A, B, C, D, E, F, G, H, I> Iterator for Zip9Iterator<A, B, C, D, E, F, G, H, I>
500where
501 A: Iterator,
502 B: Iterator,
503 C: Iterator,
504 D: Iterator,
505 E: Iterator,
506 F: Iterator,
507 G: Iterator,
508 H: Iterator,
509 I: Iterator,
510{
511 type Item = (A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item, H::Item, I::Item);
512
513 fn next(&mut self) -> Option<Self::Item> {
514 match (self.a.next(), self.b.next(), self.c.next(), self.d.next(), self.e.next(), self.f.next(), self.g.next(), self.h.next(), self.i.next()) {
515 (Some(a), Some(b), Some(c), Some(d), Some(e), Some(f), Some(g), Some(h), Some(i)) => Some((a, b, c, d, e, f, g, h, i)),
516 _ => None,
517 }
518 }
519}
520
521pub struct Zip10Iterator<A, B, C, D, E, F, G, H, I, J> {
523 a: A,
524 b: B,
525 c: C,
526 d: D,
527 e: E,
528 f: F,
529 g: G,
530 h: H,
531 i: I,
532 j: J,
533}
534
535impl<A, B, C, D, E, F, G, H, I, J> Iterator for Zip10Iterator<A, B, C, D, E, F, G, H, I, J>
536where
537 A: Iterator,
538 B: Iterator,
539 C: Iterator,
540 D: Iterator,
541 E: Iterator,
542 F: Iterator,
543 G: Iterator,
544 H: Iterator,
545 I: Iterator,
546 J: Iterator,
547{
548 type Item = (A::Item, B::Item, C::Item, D::Item, E::Item, F::Item, G::Item, H::Item, I::Item, J::Item);
549
550 fn next(&mut self) -> Option<Self::Item> {
551 match (self.a.next(), self.b.next(), self.c.next(), self.d.next(), self.e.next(), self.f.next(), self.g.next(), self.h.next(), self.i.next(), self.j.next()) {
552 (Some(a), Some(b), Some(c), Some(d), Some(e), Some(f), Some(g), Some(h), Some(i), Some(j)) => Some((a, b, c, d, e, f, g, h, i, j)),
553 _ => None,
554 }
555 }
556}
557
558#[cfg(test)]
559mod tests {
560 use super::*;
561
562 #[test]
563 fn test_zip3() {
564 let a = vec![1, 2, 3];
565 let b = vec![4, 5, 6];
566 let c = vec![7, 8, 9];
567
568 let zipped: Vec<_> = zip3(a, b, c).collect();
569 assert_eq!(zipped, vec![(1, 4, 7), (2, 5, 8), (3, 6, 9)]);
570 }
571
572 #[test]
573 fn test_zip3_with() {
574 let a = vec![1, 2, 3];
575 let b = vec![4, 5, 6];
576 let c = vec![7, 8, 9];
577
578 let result = zip3_with(|x, y, z| x + y + z, a, b, c);
579 assert_eq!(result, vec![12, 15, 18]);
580 }
581
582 #[test]
583 fn test_zip4() {
584 let a = vec![1, 2, 3];
585 let b = vec![4, 5, 6];
586 let c = vec![7, 8, 9];
587 let d = vec![10, 11, 12];
588
589 let zipped: Vec<_> = zip4(a, b, c, d).collect();
590 assert_eq!(zipped, vec![(1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)]);
591 }
592
593 #[test]
594 fn test_zip4_with() {
595 let a = vec![1, 2, 3];
596 let b = vec![4, 5, 6];
597 let c = vec![7, 8, 9];
598 let d = vec![10, 11, 12];
599
600 let result = zip4_with(|w, x, y, z| w + x + y + z, a, b, c, d);
601 assert_eq!(result, vec![22, 26, 30]);
602 }
603
604 #[test]
605 fn test_zip5() {
606 let a = vec![1, 2, 3];
607 let b = vec![4, 5, 6];
608 let c = vec![7, 8, 9];
609 let d = vec![10, 11, 12];
610 let e = vec![13, 14, 15];
611
612 let zipped: Vec<_> = zip5(a, b, c, d, e).collect();
613 assert_eq!(zipped, vec![(1, 4, 7, 10, 13), (2, 5, 8, 11, 14), (3, 6, 9, 12, 15)]);
614 }
615
616 #[test]
617 fn test_zip5_with() {
618 let a = vec![1, 2, 3];
619 let b = vec![4, 5, 6];
620 let c = vec![7, 8, 9];
621 let d = vec![10, 11, 12];
622 let e = vec![13, 14, 15];
623
624 let result = zip5_with(|v, w, x, y, z| v + w + x + y + z, a, b, c, d, e);
625 assert_eq!(result, vec![35, 40, 45]);
626 }
627
628 #[test]
629 fn test_zip_different_lengths() {
630 let a = vec![1, 2, 3, 4];
631 let b = vec![5, 6];
632 let c = vec![7, 8, 9];
633
634 let zipped: Vec<_> = zip3(a, b, c).collect();
635 assert_eq!(zipped, vec![(1, 5, 7), (2, 6, 8)]);
636 }
637
638 #[test]
639 fn test_zip_with_strings() {
640 let names = vec!["Alice", "Bob", "Charlie"];
641 let ages = vec![25, 30, 35];
642 let cities = vec!["New York", "London", "Tokyo"];
643
644 let result = zip3_with(|name, age, city| format!("{} is {} years old and lives in {}", name, age, city), names, ages, cities);
645 assert_eq!(result, vec![
646 "Alice is 25 years old and lives in New York",
647 "Bob is 30 years old and lives in London",
648 "Charlie is 35 years old and lives in Tokyo"
649 ]);
650 }
651}