在javascript中创建累积和数组

Sho*_*nna 23 javascript arrays

这是我需要做的一个例子:

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];
Run Code Online (Sandbox Code Playgroud)

所有这些都会输出5,15,18,20

但不是像这样写出所有的变量,我想要它说:

var result = arrayitem + the sum of any previous items 
Run Code Online (Sandbox Code Playgroud)

那有意义吗?那可能吗?我怎么做?

Mat*_*att 23

Javascript reduce提供了当前索引,这在这里很有用:

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]
Run Code Online (Sandbox Code Playgroud)


Poi*_*nty 15

reduce避免制作新数组的替代方法:

var result = myarray.reduce(function(r, a) {
  r.push((r.length && r[r.length - 1] || 0) + a);
  return r;
}, []);
Run Code Online (Sandbox Code Playgroud)

没有必要为每个结果重新求和子数组.

编辑同样的东西的丑陋版本:

var result = myarray.reduce(function(r, a) {
  if (r.length > 0)
    a += r[r.length - 1];
  r.push(a);
  return r;
}, []);
Run Code Online (Sandbox Code Playgroud)

  • 只需`r [r.length - 1] || 0`,不需要ifs. (2认同)

Jol*_*ker 15

Nina Scholz复制的一种优雅的解决方案,使用currying访问先前的值。

const cumulativeSum = (sum => value => sum += value)(0);

console.log([5, 10, 3, 2].map(cumulativeSum));
Run Code Online (Sandbox Code Playgroud)

cumulativeSum是函数value => sum += value,且sum初始化为零。每次调用时,sum都会进行更新,并且下次调用时(与input [n]相同)将等于前一个值(output [n-1])。

  • 很好很短,但你必须知道你只能运行它一次,因为“sum”保留其值,并且下次调用“cumulativeSum”时它将保留其旧值。因此,如果您在某个本地范围内有“cumulativeSum”并且仅在其中使用一次,则只能重复工作...... (3认同)
  • @olefrank 从一开始,sum 就是 0。cumulativeSum 是用 5 调用的,所以 `sum += 5` 将 5 添加到 `sum` 并返回 `sum`。然后用 10 调用,所以 `sum` 变成 15。然后是 3, 18 和 2, 20。 (2认同)
  • 或者将 `cumulativeSum` 定义为 `constcumulativeSum = (sum => value => sum += value);`,然后使用 `array.map(cumulativeSum(0));` 调用它 (2认同)

Pau*_*cas 9

ES6阵列传播还有更多选择

[1, 2, 3].reduce((a, x, i) => [...a, x + (a[i-1] || 0)], []); //[1, 3, 6]
Run Code Online (Sandbox Code Playgroud)

要么

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


Sha*_*lcu 6

使用 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);
Run Code Online (Sandbox Code Playgroud)

有关更多信息Array.reduce()

箭头函数


Roy*_*ook 6

我需要保留结果并添加一个运行总计属性。我有一个带有日期和收入的 json 对象,并且还想显示运行总计。

//i'm calculating a running total of revenue, here's some sample data
let a = [
  {"date":  "\/Date(1604552400000)\/","revenue":  100000 },
  {"date":  "\/Date(1604203200000)\/","revenue":  200000 },
  {"date":  "\/Date(1604466000000)\/","revenue":  125000 },
  {"date":  "\/Date(1604293200000)\/","revenue":  400000 },
  {"date":  "\/Date(1604379600000)\/","revenue":  150000 }
];

//outside accumulator to hold the running total
let c = 0;

//new obj to hold results with running total
let b = a
  .map( x => ({...x,"rtotal":c+=x.revenue}) )
  
//show results, use console.table if in a browser console
console.log(b)
Run Code Online (Sandbox Code Playgroud)


sac*_*024 5

这个解决方案怎么样

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);
Run Code Online (Sandbox Code Playgroud)

PS:你也可以使用原始数组。我只是复制它以防我们不想污染它。


geo*_*org 2

更通用(且高效)的解决方案:

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;
}
Run Code Online (Sandbox Code Playgroud)

或者

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

进而

r = [5, 10, 3, 2].accumulate(function(x, y) { return x + y })
Run Code Online (Sandbox Code Playgroud)