Skip to content

Commit b362958

Browse files
committed
Add function core::iter::zip
This makes it a little easier to `zip` iterators: ```rust for (x, y) in zip(xs, ys) {} // vs. for (x, y) in xs.into_iter().zip(ys) {} ``` You can `zip(&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 zip(zip(xs, ys), zs) {} for (x, (y, z)) in zip(xs, zip(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)) {} ``` It may also format more nicely, especially when the first iterator is a longer chain of methods -- for example: ```rust iter::zip( trait_ref.substs.types().skip(1), impl_trait_ref.substs.types().skip(1), ) // vs. trait_ref .substs .types() .skip(1) .zip(impl_trait_ref.substs.types().skip(1)) ``` This replaces the tuple-pair `IntoIterator` in rust-lang#78204. There is prior art for the utility of this in [`itertools::zip`]. [`itertools::zip`]: https://docs.rs/itertools/0.10.0/itertools/fn.zip.html
1 parent e423058 commit b362958

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

library/core/src/iter/adapters/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ pub use self::map_while::MapWhile;
5151
#[unstable(feature = "trusted_random_access", issue = "none")]
5252
pub use self::zip::TrustedRandomAccess;
5353

54+
#[unstable(feature = "iter_zip", issue = "none")]
55+
pub use self::zip::zip;
56+
5457
/// This trait provides transitive access to source-stage in an interator-adapter pipeline
5558
/// under the conditions that
5659
/// * the iterator source `S` itself implements `SourceIter<Source = S>`

library/core/src/iter/adapters/zip.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use crate::iter::{InPlaceIterable, SourceIter, TrustedLen};
55

66
/// An iterator that iterates two other iterators simultaneously.
77
///
8-
/// This `struct` is created by [`Iterator::zip`]. See its documentation
9-
/// for more.
8+
/// This `struct` is created by [`zip`] or [`Iterator::zip`].
9+
/// See their documentation for more.
1010
#[derive(Clone)]
1111
#[must_use = "iterators are lazy and do nothing unless consumed"]
1212
#[stable(feature = "rust1", since = "1.0.0")]
@@ -33,6 +33,37 @@ impl<A: Iterator, B: Iterator> Zip<A, B> {
3333
}
3434
}
3535

36+
/// Converts the arguments to iterators and zips them.
37+
///
38+
/// See the documentation of [`Iterator::zip`] for more.
39+
///
40+
/// # Examples
41+
///
42+
/// ```
43+
/// #![feature(iter_zip)]
44+
/// use std::iter::zip;
45+
///
46+
/// let xs = [1, 2, 3];
47+
/// let ys = [4, 5, 6];
48+
/// for (x, y) in zip(&xs, &ys) {
49+
/// println!("x:{}, y:{}", x, y);
50+
/// }
51+
///
52+
/// // Nested zips are also possible:
53+
/// let zs = [7, 8, 9];
54+
/// for ((x, y), z) in zip(zip(&xs, &ys), &zs) {
55+
/// println!("x:{}, y:{}, z:{}", x, y, z);
56+
/// }
57+
/// ```
58+
#[unstable(feature = "iter_zip", issue = "none")]
59+
pub fn zip<A, B>(a: A, b: B) -> Zip<A::IntoIter, B::IntoIter>
60+
where
61+
A: IntoIterator,
62+
B: IntoIterator,
63+
{
64+
ZipImpl::new(a.into_iter(), b.into_iter())
65+
}
66+
3667
#[stable(feature = "rust1", since = "1.0.0")]
3768
impl<A, B> Iterator for Zip<A, B>
3869
where

library/core/src/iter/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ pub use self::traits::{
389389
DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum,
390390
};
391391

392+
#[unstable(feature = "iter_zip", issue = "none")]
393+
pub use self::adapters::zip;
392394
#[stable(feature = "iter_cloned", since = "1.1.0")]
393395
pub use self::adapters::Cloned;
394396
#[stable(feature = "iter_copied", since = "1.36.0")]

0 commit comments

Comments
 (0)