Skip to content

Instantly share code, notes, and snippets.

@aleneum
Last active June 18, 2024 17:22
Show Gist options
  • Save aleneum/7990a334072858fc847159a5ebd78521 to your computer and use it in GitHub Desktop.
Save aleneum/7990a334072858fc847159a5ebd78521 to your computer and use it in GitHub Desktop.
Iterate and store partial results as a new iterator
pub struct ScanMap<I, F, T> {
iter: I,
f: F,
acc: T,
}
impl<I, F, T> ScanMap<I, F, T>
where
I: Iterator,
F: FnMut(&T, I::Item) -> T,
T: Clone,
{
fn new(iter: I, acc: T, f: F) -> Self {
Self { iter, f, acc }
}
}
impl<I, F, T> Iterator for ScanMap<I, F, T>
where
I: Iterator,
F: FnMut(&T, I::Item) -> T,
T: Clone,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.acc = (self.f)(&self.acc, self.iter.next()?);
Some(self.acc.clone())
}
}
pub trait ScanMapExt: Iterator {
fn scan_map<T, F>(self, acc: T, f: F) -> ScanMap<Self, F, T>
where
Self: Sized,
F: FnMut(&T, Self::Item) -> T,
T: Clone,
{
ScanMap::new(self, acc, f)
}
}
impl<I: Iterator> ScanMapExt for I {}
mod scan_map;
use scan_map::ScanMapExt;
fn main() {
let v = [1, 2, 3, 4];
let result: Vec<_> = v.iter().scan_map(0, |acc, x| acc + x).collect();
println!("{:?}", result); // Outputs: [1, 3, 6, 10]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment