Creating an array of cumulative sum in javascript

后端 未结 21 1502
时光取名叫无心
时光取名叫无心 2020-11-27 06:23

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         


        
相关标签:
21条回答
  • 2020-11-27 07:11

    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]
    
    0 讨论(0)
  • 2020-11-27 07:12

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

    0 讨论(0)
  • 2020-11-27 07:13

    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.

    0 讨论(0)
  • 2020-11-27 07:14

    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, []);
    
    0 讨论(0)
  • 2020-11-27 07:15

    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;
    }, []);
    
    0 讨论(0)
  • 2020-11-27 07:15

    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.

    0 讨论(0)
提交回复
热议问题