 # Inplace cumulative sum using iterator

I'm trying to make a cumsum vec, but replacing the values inside the vec, so that I can avoid an allocation.

Something like

``````let a_vec = vec![1.0; 10];
let cumsum: Vec<f64> = a_vec
.iter()
.scan(0.0, |acc, &x| {
*acc += x;
Some(*acc)
})
.collect();
``````

but replacing values.

1 Like

I guess, you could just use a `for`-loop. E.g.:

``````let mut a_vec = vec![1.0; 10];
let mut acc = 0.0;
for x in &mut a_vec {
acc += *x;
*x = acc;
}
// a_vec now contains cumulative sum(s)
``````
1 Like

I like the `for` loop, but just for comparison, you could also write it as:

``````let mut a_vec = vec![1.0; 10];

a_vec.iter_mut().fold(0.0, |acc, x| {
*x += acc;
*x
});
``````
1 Like

I knew I could use a for loop. I was looking for a version using iterators.

Thanks.

ACTUALLY... through some use of specialization in the standard library today, especially involving traits such as `SourceIter` and `InPlaceIterable` that `Scan` implements, if you just consume the vector (using `into_iter` instead of `iter`), the operation gets compiled as an inplace operation without any extra allocation despite the use of `.collect()`.

I mean, just use `into_iter` and remove one `&`

``````let a_vec = vec![1.0; 10];
let cumsum: Vec<f64> = a_vec
.into_iter()
.scan(0.0, |acc, x| {
*acc += x;
Some(*acc)
})
.collect();
``````

You can use `{:p}` formatter for printing the addresses of the allocations to see that it’s really inplace

``````let a_vec = vec![1.0; 10];
println!("{:p}", &a_vec[..]);
let cumsum: Vec<f64> = a_vec
.into_iter()
.scan(0.0, |acc, x| {
*acc += x;
Some(*acc)
})
.collect();
println!("{:p}", &cumsum[..]);
``````
``````0x560483cf8ad0