这是我需要做的一个例子:
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];
所以这一切都会输出5,15,18,20
但不是像这样写出所有的变种,我想要它说:
var result = arrayitem + the sum of any previous items
这有意义吗?那可能吗?我怎么做?
答案 0 :(得分:22)
Javascript' s 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]
答案 1 :(得分:14)
避免制作新数组的替代reduce
方法:
var result = myarray.reduce(function(r, a) {
r.push((r.length && r[r.length - 1] || 0) + a);
return r;
}, []);
没有必要为每个结果重新排列子数组。
编辑同一件事的丑陋版本:
var result = myarray.reduce(function(r, a) {
if (r.length > 0)
a += r[r.length - 1];
r.push(a);
return r;
}, []);
答案 2 :(得分:6)
ES6阵列传播的另外两个选项
[1, 2, 3].reduce((a, x, i) => [...a, x + (a[i-1] || 0)], []); //[1, 3, 6]
或
[3, 2, 1].reduce((a, x, i) => [...a, a.length > 0 ? x + a[i-1] : x], []); //[3, 5, 6]
答案 3 :(得分:5)
从Nina Scholz复制的一种优雅的解决方案,使用currying访问先前的值。
const cumulativeSum = (sum => value => sum += value)(0);
console.log([5, 10, 3, 2].map(cumulativeSum));
cumulativeSum
是函数value => sum += value
,其中sum
初始化为零。每次调用sum
时,都会更新RewriteEngine on
RewriteCond $1 !^(index\.php|public|\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1
,并且下次调用{input [n]]时,它将等于先前的值(output [n-1])。
答案 4 :(得分:4)
使用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);

了解更多信息Array.reduce()
答案 5 :(得分:3)
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:您也可以使用原始数组。我只是复制它,以防我们不想污染它。
答案 6 :(得分:1)
另一个带有reduce和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]
答案 7 :(得分:1)
这个问题已经被其他人很好地回答了,但我也将解决方案留在这里。我试图保持简洁而不牺牲清晰度。
myarray.reduce((a, e, i) => {
// a: Accumulator; e: current Element; i: current Index
return a.length > 0 ? [...a, e + a[i - 1]] : [e];
}, []);
地图,过滤器,缩小,查找,某些等被低估了。
答案 8 :(得分:1)
/**
* 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)
})
答案 9 :(得分:1)
使用array-reduce的简单功能。
TotalReturns
答案 10 :(得分:1)
我最初的ES6想法类似于Taeho和其他人的一些上述答案。
const cumulativeSum = ([head, ...tail]) =>
tail.reduce((acc, x, index) => {
acc.push(acc[index] + x);
return acc
}, [head])
console.log(cumulativeSum([-1,2,3])
解决方案执行:
n次查找,n - 1次总和和0次条件评估
我上面看到的大部分内容似乎都在使用:
n次查找,2n次总和,以及n次条件评估:
您也可以使用ie6安全js执行此操作。这可能更有效,因为您不必创建尾部扩展数组。
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]))
答案 11 :(得分:1)
更通用(且更有效)的解决方案:
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;
}
或
Array.prototype.accumulate = function(fn) {
var r = [this[0]];
this.reduce(function(a, b) {
return r[r.length] = fn(a, b);
});
return r;
}
然后
r = [5, 10, 3, 2].accumulate(function(x, y) { return x + y })
答案 12 :(得分:1)
使用for循环的简单解决方案
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)
答案 13 :(得分:1)
使用reduce直接和非破坏性地构建结果。
a.reduce(function(r,c,i){ r.push((r[i-1] || 0) + c); return r }, [] );
答案 14 :(得分:0)
使用箭头函数代替函数,使用逗号运算符代替return,使用currentIndex减少回调。
[5, 10, 3, 2].reduce((r, a, i) => (r.push((i && r[i - 1] || 0) + a), r), []); // [ 5, 15, 18, 20 ]
答案 15 :(得分:0)
为了将cumsum保持在函数中直到完全构建,我在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, []);
以下是它的工作原理:
past_sums.slice(-1) === []
1*past_sums.slice(-1) === 0
cumsum
返回[past_sums
和new_sum
]作为下一个周期的past_sums
cumsum
返回[5, 15, 18, 20]
作为输出数组some_sums
var cumsum = function(sums, val) {
return sums.concat([ val + 1*sums.slice(-1) ]);
}
var some_sums = [5, 10, 3, 2].reduce(cumsum, []);
使用箭头函数(Not for ≤IE11 or Opera Mini),我写这个:
var cumsum = (sums,val) => sums.concat([ val + 1*sums.slice(-1) ]);
var some_sums = [5, 10, 3, 2].reduce(cumsum, []);
答案 16 :(得分:0)
按键和排序数组返回已排序的obj !!!
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,...}
答案 17 :(得分:0)
守旧而简单:
let myarray = [5, 10, 3, 2], result = [];
for (let i = 0, s = myarray[0]; i < myarray.length; i++, s += myarray[i]) result.push(s);
console.log(result); // [5, 15, 18, 20]
答案 18 :(得分:0)
我需要保留结果并仅添加运行中的total属性。我有一个带有日期和收入的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)
答案 19 :(得分:0)
/ *查看下面的说明* /
nums = [1,2,3,4]
var runningSum = function(nums) {
shoppingCart =[];
runningtotal =0;
nums.forEach(EachValue => {
runningtotal += EachValue
shoppingCart.push(runningtotal);
});
return shoppingCart
};
console.log(runningSum(nums));
/ *定义一些数字* /
nums = [1,2,3,4]
/ *分配功能runningSum,一些数字* /
var runningSum = function(nums) {
shoppingCart =[]; /* Create a empty shopping cart to store the items */
runningtotal =0; /* Start with your beginning bill of zero items in the cart */
/ *从数字列表中删除一个数字,使用指针函数从数组中调用每个数字=> EachValue * /
nums.forEach(EachValue => {
(runningtotal += EachValue)
/ *现在将值添加到运行总计以表示商品价格* /
shoppingCart.push(runningtotal);
/ *使用push方法将其放入称为购物车的新数组* / });
返回购物车
/ *仅以1d价格输出当前购物车中的商品* /
};
nums = [1,2,3,4]
var runningSum = function(nums) {
shoppingCart =[];
runningtotal =0;
nums.forEach(EachValue => {
runningtotal += EachValue
shoppingCart.push(runningtotal);
});
return shoppingCart
};
console.log(runningSum(nums));
答案 20 :(得分:0)
var nums= [5, 10, 3, 2];
var runningSum = function(nums) {
nums.reduce((acc, _, i) => (nums[i] += acc));
return nums;
};
答案 21 :(得分:0)
我使用array.map()
提出了这个ES6版本
function prefixSum(nums) {
let psum = 0;
return nums.map(x => psum += x);
};
console.log(prefixSum([5, 10, 20, 30]));