I want to apply a reduction to an iterator, but I don't need just the final value, the intermediate results are important, too.
As an example, let's convert a vector of offsets to a vector of positions:
let offsets = vec![3, 2, 1, 4];
// create positions vector [3, 5, 6, 10]
My attempt at a solution uses map
and a closure:
let mut acc = 0;
let positions: Vec<i32> = offsets
.iter()
.map(|x| {
acc = acc + x;
acc
})
.collect();
Good comment from @starblue: To do a cumulative sum, fold
would be the best option. It applies a reduction and returns the last value. It doesn't return intermediate solutions though:
// basically exact code from fold example in the docs
let last_position = offsets.iter().fold(0, |acc, x| acc + x);
I see that I should have read the docs more carefully. The function I'm looking for is called scan
. Here is a cumulative sum implementation:
let offsets = vec![3, 2, 1, 4];
let positions: Vec<i32> = offsets
.iter()
.scan(0, |acc, &x| {
*acc = *acc + x;
Some(*acc)
})
.collect();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With