Skip to content

Commit b96a62c

Browse files
committed
with_prev
Co-authored-by: Warren Wise <[email protected]>
1 parent 2ec463c commit b96a62c

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

src/lib.rs

+22
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;
@@ -1801,6 +1803,26 @@ pub trait Itertools: Iterator {
18011803
with_position::with_position(self)
18021804
}
18031805

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

src/with_prev.rs

+41
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)