Skip to content

Commit

Permalink
with_prev
Browse files Browse the repository at this point in the history
Co-authored-by: Warren Wise <warren.a.wise@gmail.com>
  • Loading branch information
2 people authored and mightyiam committed Oct 14, 2023
1 parent 0951795 commit 8d71794
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/lib.rs
Expand Up @@ -133,6 +133,7 @@ pub mod structs {
#[cfg(feature = "use_std")]
pub use crate::unique_impl::{Unique, UniqueBy};
pub use crate::with_position::WithPosition;
pub use crate::with_prev::WithPrev;
pub use crate::zip_eq_impl::ZipEq;
pub use crate::zip_longest::ZipLongest;
pub use crate::ziptuple::Zip;
Expand Down Expand Up @@ -222,6 +223,7 @@ mod tuple_impl;
mod unique_impl;
mod unziptuple;
mod with_position;
mod with_prev;
mod zip_eq_impl;
mod zip_longest;
mod ziptuple;
Expand Down Expand Up @@ -1804,6 +1806,26 @@ pub trait Itertools: Iterator {
with_position::with_position(self)
}

/// Return an iterator adaptor that combines each element except the first with
/// a clone of the previous.
///
/// ```
/// use itertools::Itertools;
///
/// let it = (0..4).with_prev();
/// itertools::assert_equal(it,
/// vec![(None, 0),
/// (Some(0), 1),
/// (Some(1), 2),
/// (Some(2), 3)]);
/// ```
fn with_prev(self) -> WithPrev<Self>
where
Self: Sized,
{
with_prev::with_prev(self)
}

/// Return an iterator adaptor that yields the indices of all elements
/// satisfying a predicate, counted from the start of the iterator.
///
Expand Down
41 changes: 41 additions & 0 deletions src/with_prev.rs
@@ -0,0 +1,41 @@
/// An iterator adaptor that combines each element except the first with a clone of the previous.
///
/// See [`.with_prev()`](crate::Itertools::with_prev) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct WithPrev<I>
where
I: Iterator,
{
iter: I,
prev: Option<I::Item>,
}

impl<I> Clone for WithPrev<I>
where
I: Clone + Iterator,
I::Item: Clone,
{
clone_fields!(iter, prev);
}

/// Create a new `WithPrev` iterator.
pub fn with_prev<I>(iter: I) -> WithPrev<I>
where
I: Iterator,
{
WithPrev { iter, prev: None }
}

impl<I> Iterator for WithPrev<I>
where
I: Iterator,
I::Item: Clone,
{
type Item = (Option<I::Item>, I::Item);

fn next(&mut self) -> Option<Self::Item> {
let next = self.iter.next()?;
let prev = std::mem::replace(&mut self.prev, Some(next.clone()));
Some((prev, next))
}
}

0 comments on commit 8d71794

Please sign in to comment.