Expand docs on Iterator::intersperse

This commit is contained in:
Lukas Lueg 2021-01-18 20:40:25 +01:00
parent 5e91c4ecc0
commit 653bcc8ad2
2 changed files with 52 additions and 9 deletions

View File

@ -151,12 +151,10 @@ where
{ {
let (lo, hi) = iter.size_hint(); let (lo, hi) = iter.size_hint();
let next_is_elem = !needs_sep; let next_is_elem = !needs_sep;
let lo = lo.saturating_sub(next_is_elem as usize).saturating_add(lo); (
let hi = match hi { lo.saturating_sub(next_is_elem as usize).saturating_add(lo),
Some(hi) => hi.saturating_sub(next_is_elem as usize).checked_add(hi), hi.and_then(|hi| hi.saturating_sub(next_is_elem as usize).checked_add(hi)),
None => None, )
};
(lo, hi)
} }
fn intersperse_fold<I, B, F, G>( fn intersperse_fold<I, B, F, G>(

View File

@ -569,9 +569,10 @@ pub trait Iterator {
Zip::new(self, other.into_iter()) Zip::new(self, other.into_iter())
} }
/// Places a copy of `separator` between all elements. /// Creates a new iterator which places a copy of `separator` between adjacent
/// items of the original iterator.
/// ///
/// In case the separator does not implement [`Clone`] or needs to be /// In case `separator` does not implement [`Clone`] or needs to be
/// computed every time, use [`intersperse_with`]. /// computed every time, use [`intersperse_with`].
/// ///
/// # Examples /// # Examples
@ -581,6 +582,19 @@ pub trait Iterator {
/// ``` /// ```
/// #![feature(iter_intersperse)] /// #![feature(iter_intersperse)]
/// ///
/// let mut a = [0, 1, 2].iter().intersperse(&100);
/// assert_eq!(a.next(), Some(&0)); // The first element from `a`.
/// assert_eq!(a.next(), Some(&100)); // The separator.
/// assert_eq!(a.next(), Some(&1)); // The next element from `a`.
/// assert_eq!(a.next(), Some(&100)); // The separator.
/// assert_eq!(a.next(), Some(&2)); // The last element from `a`.
/// assert_eq!(a.next(), None); // The iterator is finished.
/// ```
///
/// `intersperse` can be very useful to join an iterator's items using a common element:
/// ```
/// #![feature(iter_intersperse)]
///
/// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>(); /// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
/// assert_eq!(hello, "Hello World !"); /// assert_eq!(hello, "Hello World !");
/// ``` /// ```
@ -597,7 +611,16 @@ pub trait Iterator {
Intersperse::new(self, separator) Intersperse::new(self, separator)
} }
/// Places an element generated by `separator` between all elements. /// Creates a new iterator which places an item generated by `separator`
/// between adjacent items of the original iterator.
///
/// The closure will be called exactly once each time an item is placed
/// between two adjacent items from the underlying iterator; specifically,
/// the closure is not called if the underlying iterator yields less than
/// two items and after the last item is yielded.
///
/// If the iterator's item implements [`Clone`], it may be easier to use
/// [`intersperse`].
/// ///
/// # Examples /// # Examples
/// ///
@ -606,14 +629,36 @@ pub trait Iterator {
/// ``` /// ```
/// #![feature(iter_intersperse)] /// #![feature(iter_intersperse)]
/// ///
/// #[derive(PartialEq, Debug)]
/// struct NotClone(usize);
///
/// let v = vec![NotClone(0), NotClone(1), NotClone(2)];
/// let mut it = v.into_iter().intersperse_with(|| NotClone(99));
///
/// assert_eq!(it.next(), Some(NotClone(0))); // The first element from `v`.
/// assert_eq!(it.next(), Some(NotClone(99))); // The separator.
/// assert_eq!(it.next(), Some(NotClone(1))); // The next element from `v`.
/// assert_eq!(it.next(), Some(NotClone(99))); // The separator.
/// assert_eq!(it.next(), Some(NotClone(2))); // The last element from from `v`.
/// assert_eq!(it.next(), None); // The iterator is finished.
/// ```
///
/// `intersperse_with` can be used in situations where the separator needs
/// to be computed:
/// ```
/// #![feature(iter_intersperse)]
///
/// let src = ["Hello", "to", "all", "people", "!!"].iter().copied(); /// let src = ["Hello", "to", "all", "people", "!!"].iter().copied();
/// ///
/// // The closure mutably borrows it's context to generate an item.
/// let mut happy_emojis = [" ❤️ ", " 😀 "].iter().copied(); /// let mut happy_emojis = [" ❤️ ", " 😀 "].iter().copied();
/// let separator = || happy_emojis.next().unwrap_or(" 🦀 "); /// let separator = || happy_emojis.next().unwrap_or(" 🦀 ");
/// ///
/// let result = src.intersperse_with(separator).collect::<String>(); /// let result = src.intersperse_with(separator).collect::<String>();
/// assert_eq!(result, "Hello ❤️ to 😀 all 🦀 people 🦀 !!"); /// assert_eq!(result, "Hello ❤️ to 😀 all 🦀 people 🦀 !!");
/// ``` /// ```
/// [`Clone`]: crate::clone::Clone
/// [`intersperse`]: Iterator::intersperse
#[inline] #[inline]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G> fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>