Skip to content

Commit

Permalink
impl<A, B> IntoIterator for (A, B) as Zip
Browse files Browse the repository at this point in the history
This makes it a little easier to `zip` iterators:

```rust
for (x, y) in (xs, ys) {}
// vs.
for (x, y) in xs.into_iter().zip(ys) {}
```

You can iterate `(&mut xs, &ys)` for the conventional `iter_mut()` and
`iter()`, respectively. This can also support arbitrary nesting, where
it's easier to see the item layout than with arbitrary `zip` chains:

```rust
for ((x, y), z) in ((xs, ys), zs) {}
for (x, (y, z)) in (xs, (ys, zs)) {}
// vs.
for ((x, y), z) in xs.into_iter().zip(ys).zip(xz) {}
for (x, (y, z)) in xs.into_iter().zip((ys.into_iter().zip(xz)) {}
```

Only tuple pairs are implemented for now. It's possible to implement
longer tuples, but that would require a new iterator type to produce
those tuple items. See itertools' [`Zip`] and rayon's [`MultiZip`] for
prior art there.

[`Zip`]: https://docs.rs/itertools/0.9.0/itertools/structs/struct.Zip.html
[`MultiZip`]: https://docs.rs/rayon/1.4.1/rayon/iter/struct.MultiZip.html

See also rust-lang/rfcs#870 and rust-lang/rfcs#930.
  • Loading branch information
cuviper committed Oct 21, 2020
1 parent 1d27267 commit 4decb2c
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions library/core/src/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use crate::cmp::Ordering::*;
use crate::cmp::*;
use crate::iter::{IntoIterator, Zip};

// macro for implementing n-ary tuple functions and operations
macro_rules! tuple_impls {
Expand Down Expand Up @@ -211,3 +212,39 @@ tuple_impls! {
(11) -> L
}
}

/// Converts a pair of `IntoIterator` values into a single iterator of pairs
///
/// This works like an implicit [`zip`] in any context that accepts `IntoIterator`
/// values, like [`chain`], [`flat_map`], and especially `for` loops.
///
/// ```
/// let xs = [1, 2, 3];
/// let ys = [4, 5, 6];
/// for (x, y) in (&xs, &ys) {
/// println!("x:{}, y:{}", x, y);
/// }
///
/// // Nested zips are also possible:
/// let zs = [7, 8, 9];
/// for ((x, y), z) in ((&xs, &ys), &zs) {
/// println!("x:{}, y:{}, z:{}", x, y, z);
/// }
/// ```
///
/// [`chain`]: Iterator::chain
/// [`flat_map`]: Iterator::flat_map
/// [`zip`]: Iterator::zip
#[stable(feature = "pair_into_iter", since = "1.49.0")]
impl<A, B> IntoIterator for (A, B)
where
A: IntoIterator,
B: IntoIterator,
{
type IntoIter = Zip<A::IntoIter, B::IntoIter>;
type Item = (A::Item, B::Item);

fn into_iter(self) -> Self::IntoIter {
self.0.into_iter().zip(self.1)
}
}

0 comments on commit 4decb2c

Please sign in to comment.