Skip to content

Commit 8d71794

Browse files
warren2kmightyiam
authored andcommitted
with_prev
Co-authored-by: Warren Wise <[email protected]>
1 parent 0951795 commit 8d71794

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ pub mod structs {
133133
#[cfg(feature = "use_std")]
134134
pub use crate::unique_impl::{Unique, UniqueBy};
135135
pub use crate::with_position::WithPosition;
136+
pub use crate::with_prev::WithPrev;
136137
pub use crate::zip_eq_impl::ZipEq;
137138
pub use crate::zip_longest::ZipLongest;
138139
pub use crate::ziptuple::Zip;
@@ -222,6 +223,7 @@ mod tuple_impl;
222223
mod unique_impl;
223224
mod unziptuple;
224225
mod with_position;
226+
mod with_prev;
225227
mod zip_eq_impl;
226228
mod zip_longest;
227229
mod ziptuple;
@@ -1804,6 +1806,26 @@ pub trait Itertools: Iterator {
18041806
with_position::with_position(self)
18051807
}
18061808

1809+
/// Return an iterator adaptor that combines each element except the first with
1810+
/// a clone of the previous.
1811+
///
1812+
/// ```
1813+
/// use itertools::Itertools;
1814+
///
1815+
/// let it = (0..4).with_prev();
1816+
/// itertools::assert_equal(it,
1817+
/// vec![(None, 0),
1818+
/// (Some(0), 1),
1819+
/// (Some(1), 2),
1820+
/// (Some(2), 3)]);
1821+
/// ```
1822+
fn with_prev(self) -> WithPrev<Self>
1823+
where
1824+
Self: Sized,
1825+
{
1826+
with_prev::with_prev(self)
1827+
}
1828+
18071829
/// Return an iterator adaptor that yields the indices of all elements
18081830
/// satisfying a predicate, counted from the start of the iterator.
18091831
///

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)