Skip to content

Commit 42b0b3b

Browse files
warren2kmightyiam
authored andcommitted
with_prev
Co-authored-by: Warren Wise <warren.a.wise@gmail.com>
1 parent 86ec635 commit 42b0b3b

2 files changed

Lines changed: 63 additions & 0 deletions

File tree

src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ pub mod structs {
147147
#[cfg(feature = "use_std")]
148148
pub use crate::unique_impl::{Unique, UniqueBy};
149149
pub use crate::with_position::WithPosition;
150+
pub use crate::with_prev::WithPrev;
150151
pub use crate::zip_eq_impl::ZipEq;
151152
pub use crate::zip_longest::ZipLongest;
152153
pub use crate::ziptuple::Zip;
@@ -243,6 +244,7 @@ mod tuple_impl;
243244
mod unique_impl;
244245
mod unziptuple;
245246
mod with_position;
247+
mod with_prev;
246248
mod zip_eq_impl;
247249
mod zip_longest;
248250
mod ziptuple;
@@ -2247,6 +2249,26 @@ pub trait Itertools: Iterator {
22472249
with_position::with_position(self)
22482250
}
22492251

2252+
/// Return an iterator adaptor that combines each element except the first with
2253+
/// a clone of the previous.
2254+
///
2255+
/// ```
2256+
/// use itertools::Itertools;
2257+
///
2258+
/// let it = (0..4).with_prev();
2259+
/// itertools::assert_equal(it,
2260+
/// vec![(None, 0),
2261+
/// (Some(0), 1),
2262+
/// (Some(1), 2),
2263+
/// (Some(2), 3)]);
2264+
/// ```
2265+
fn with_prev(self) -> WithPrev<Self>
2266+
where
2267+
Self: Sized,
2268+
{
2269+
with_prev::with_prev(self)
2270+
}
2271+
22502272
/// Return an iterator adaptor that yields the indices of all elements
22512273
/// satisfying a predicate, counted from the start of the iterator.
22522274
///

src/with_prev.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/// An iterator adaptor that combines each element except the first with a clone of the previous.
2+
///
3+
/// See [`.with_prev()`](crate::Itertools::with_prev) for more information.
4+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
5+
pub struct WithPrev<I>
6+
where
7+
I: Iterator,
8+
{
9+
iter: I,
10+
prev: Option<I::Item>,
11+
}
12+
13+
impl<I> Clone for WithPrev<I>
14+
where
15+
I: Clone + Iterator,
16+
I::Item: Clone,
17+
{
18+
clone_fields!(iter, prev);
19+
}
20+
21+
/// Create a new `WithPrev` iterator.
22+
pub fn with_prev<I>(iter: I) -> WithPrev<I>
23+
where
24+
I: Iterator,
25+
{
26+
WithPrev { iter, prev: None }
27+
}
28+
29+
impl<I> Iterator for WithPrev<I>
30+
where
31+
I: Iterator,
32+
I::Item: Clone,
33+
{
34+
type Item = (Option<I::Item>, I::Item);
35+
36+
fn next(&mut self) -> Option<Self::Item> {
37+
let next = self.iter.next()?;
38+
let prev = std::mem::replace(&mut self.prev, Some(next.clone()));
39+
Some((prev, next))
40+
}
41+
}

0 commit comments

Comments
 (0)