# Creating an array of cumulative sum in javascript

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[2] + myarray[1] + myarray[0];
var result4 = myarray[3] + myarray[2] + myarray[1] + myarray[0];
``````

so all that would output 5, 15, 18, 20

but instead of writing out all the vars like that, I want it to say something like:

``````var result = arrayitem + the sum of any previous items
``````

Does that make sense? Is that possible? How do I do that?

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]).

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;
}, []);
``````

A couple more options with ES6 array spreading

``````[1, 2, 3].reduce((a, x, i) => [...a, x + (a[i-1] || 0)], []); //[1, 3, 6]
``````

or

``````[3, 2, 1].reduce((a, x, i) => [...a, a.length > 0 ? x + a[i-1] : x], []); //[3, 5, 6]
``````

Simple solution using ES6

``````let myarray = [5, 10, 3, 2];
let new_array = [];
myarray.reduce( (prev, curr,i) =>  new_array[i] = prev + curr , 0 )
console.log(new_array);``````

Arrow function

``````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.

A more generic (and efficient) solution:

``````Array.prototype.accumulate = function(fn) {
var r = [this[0]];
for (var i = 1; i < this.length; i++)
r.push(fn(r[i - 1], this[i]));
return r;
}
``````

or

``````Array.prototype.accumulate = function(fn) {
var r = [this[0]];
this.reduce(function(a, b) {
return r[r.length] = fn(a, b);
});
return r;
}
``````

and then

``````r = [5, 10, 3, 2].accumulate(function(x, y) { return x + y })
``````

use reduce to build the result directly and non-destructively.

``````a.reduce(function(r,c,i){ r.push((r[i-1] || 0) + c); return r }, [] );
``````

Simple solution using for loop

``````var myarray = [5, 10, 3, 2];

var output = [];
var sum = 0;

for(var i in myarray){
sum=sum+myarray[i];
output.push(sum)
}
console.log(output)
``````

https://jsfiddle.net/p31p877q/1/

Another clean one line solution with reduce and concat

``````var result = myarray.reduce(function(a,b,i){ return i === 0 ?  [b]: a.concat(a[i-1]+b);},0);
//[5, 10, 3, 2] => [5, 15, 18, 20]
``````

My initial ES6 thought was similar to a few above answers by Taeho and others.

``````const cumulativeSum = ([head, ...tail]) =>
tail.reduce((acc, x, index) => {
acc.push(acc[index] + x);
return acc
console.log(cumulativeSum([-1,2,3])
``````

The solution performs:

n lookups, n - 1 sums and 0 conditional evaluations

Most of what I saw above appeared to use:

n lookups, 2n sums, and n conditional evaluations:

You could do this with ie6 safe js as well. This is possibly more efficient since you don't have to create the tail spread array.

``````function cumulativeSum(a) {
var result = [a[0]];
var last = a[0];
for (i = 1; i < a.length; i++) {
last = last + a[i];
result.push(last)
}
return result;
}
console.log(cumulativeSum([-1,2,3]))
``````

A simple function using array-reduce.

``````const arr = [6, 3, -2, 4, -1, 0, -5];

const prefixSum = (arr) => {

let result = [arr[0]]; // The first digit in the array don't change
arr.reduce((accumulator, current) => {
result.push(accumulator + current);

return accumulator + current; // update accumulator
});
return result;
}
``````
``````/**
* Turn an array of numbers to cumulative sum array
* @param { Array } [1,2,3,4,5]
* @return { Array } [1,3,6,10,15]
*/

const accumulate = (a, c) => a + c

const cusum = arr => arr.map((v, i, data) => {
return data.slice(0, i + 1).reduce(accumulate)
})
``````

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.

Returns sorted obj by key and sorted array!!!

``````var unsorted_obj = {
"2016-07-01": 25,
"2016-07-04": 55,
"2016-07-05": 84,
"2016-07-06": 122,
"2016-07-03": 54,
"2016-07-02": 43
};

var sort_obj = function(obj){
var keys = [];
var sorted_arr = [];
var sorted_obj = {};

for(var key in obj){
if(obj.hasOwnProperty(key)){
keys.push(key);
}
}

keys.sort();

jQuery.each(keys, function(i, key){
sorted_obj[key] = obj[key];
var val = obj[key];
sorted_arr.push({
idx: i,
date: key,
val: val
})
});

return { sorted_obj: sorted_obj, sorted_arr: sorted_arr };

};

var sorted_obj = sort_obj(unsorted_obj).sorted_obj;
var sorted_arr = sort_obj(unsorted_obj).sorted_arr;

// sorted_arr = [{"idx":0,"date":"2016-07-01","val":25},{"idx":1,"date":"2016-07-02","val":43},{"idx":2,"date":"2016-07-03","val":54},...]
// sorted_obj = {"2016-07-01":25,"2016-07-02":43,"2016-07-03":54,...}
``````

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:

• The first cycle:
• `past_sums.slice(-1) === []`
• `1*past_sums.slice(-1) === 0`
• All but the last cycle:
• `cumsum` returns [`past_sums` and `new_sum`] as next cycle's `past_sums`
• The last cycle:
• `cumsum` returns `[5, 15, 18, 20]` as the output Array `some_sums`

# It can be written with fewer lines:

``````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, []);
``````

Use arrow function instead of function, comma operator instead of return, and currentIndex in reduce callback.

``````[5, 10, 3, 2].reduce((r, a, i) => (r.push((i && r[i - 1] || 0) + a), r), []); // [ 5, 15, 18, 20 ]
``````