This is an example of what I need to do:
var myarray = [5, 10, 3, 2];
var result1 = myarray[0];
var result2 = myarray[1] + myarray[0];
var result3 = myarray
Javascript's reduce
provides the current index, which is useful here:
var myarray = [5, 10, 3, 2];
var new_array = [];
myarray.reduce(function(a,b,i) { return new_array[i] = a+b; },0);
new_array // [5, 15, 18, 20]
An elegant solution copied from Nina Scholz, using currying to access the previous value.
const cumulativeSum = (sum => value => sum += value)(0);
console.log([5, 10, 3, 2].map(cumulativeSum));
cumulativeSum
is the function value => sum += value
, with sum
initialized to zero. Every time it's called, sum
is updated and will equal the previous value (output[n-1]) when called the next time (with input[n]).
This question has been answered well by others but I'll leave my solution here too. I tried to be concise without sacrificing clarity.
myarray.reduce((a, e, i) => {
// a: Accumulator; e: current Element; i: current Index
return a.length > 0 ? [...a, e + a[i - 1]] : [e];
}, []);
Map, Filter, Reduce, Find, Some, etc. are highly underrated.
To keep the cumsum within a function until fully built, I offer this minor variant on Matt's Answer:
var cumsum = function(past_sums, new_value) {
var last_sum = 1*past_sums.slice(-1);
var new_sum = last_sum + new_value;
return past_sums.concat([new_sum]);
}
var some_sums = [5, 10, 3, 2].reduce(cumsum, []);
Here's how it works:
past_sums.slice(-1) === []
1*past_sums.slice(-1) === 0
cumsum
returns [past_sums
and new_sum
] as next cycle's past_sums
cumsum
returns [5, 15, 18, 20]
as the output Array some_sums
var cumsum = function(sums, val) {
return sums.concat([ val + 1*sums.slice(-1) ]);
}
var some_sums = [5, 10, 3, 2].reduce(cumsum, []);
With Arrow Functions (Not for ≤IE11 or Opera Mini), I'd write this:
var cumsum = (sums,val) => sums.concat([ val + 1*sums.slice(-1) ]);
var some_sums = [5, 10, 3, 2].reduce(cumsum, []);
Alternative reduce
approach that avoids making new arrays:
var result = myarray.reduce(function(r, a) {
r.push((r.length && r[r.length - 1] || 0) + a);
return r;
}, []);
There's no need to re-sum the subarrays for each result.
edit less ugly version of the same thing:
var result = myarray.reduce(function(r, a) {
if (r.length > 0)
a += r[r.length - 1];
r.push(a);
return r;
}, []);
How about this solution
var new_array = myarray.concat(); //Copy initial array
for (var i = 1; i < myarray.length; i++) {
new_array[i] = new_array[i-1] + myarray[i];
}
console.log(new_array);
PS: You can use the original array as well. I just copied it in case we don't want to pollute it.