Javascript 如何使用forEach制作部分和列表

Javascript 如何使用forEach制作部分和列表,javascript,arrays,ecmascript-6,foreach,Javascript,Arrays,Ecmascript 6,Foreach,我有一个数组,如下所示: changes = [ [1, 1, 1, -1], [1, -1, -1], [1, 1] ]; 我想通过添加最后一个值来获取数组中的下一个值 values = [ [1, 2, 3, 2], [1, 0, -1], [1, 2] ]; 到目前为止,我已尝试使用forEach: changes.forEach(change => { let i = changes.indexOf(change); let newValue = change[

我有一个数组,如下所示:

changes = [ [1, 1, 1, -1], [1, -1, -1], [1, 1] ];
我想通过添加最后一个值来获取数组中的下一个值

values = [ [1, 2, 3, 2], [1, 0, -1], [1, 2] ];
到目前为止,我已尝试使用forEach:

changes.forEach(change => {
    let i = changes.indexOf(change);
    let newValue = change[i] + change[i + 1]
});
我认为我的思路是正确的,但我无法使这种方法发挥作用,或者可能有更好的方法来实现它。

您可以使用数组函数
const changes=[[1,1,1,-1],[1,-1,-1],[1,1];
const result=changes.map((v)=>v.slice(0).map((t,i,arr)=>i==0?t:(arr[i]+=arr[i-1]))
控制台日志(更改);
控制台日志(结果)
const changes=[[1,1,1,-1],[1,-1,-1],[1,1]]
让值=[]
更改。forEach(arr=>{
设accu=0
让nestedArr=[]
arr.forEach(n=>{
累计+=n
nestedArr推力(累计)
})
值。推送(nestedArr)
})

console.log(值)
您可以保存一个总和并添加值

var数组=[[1,1,1,-1],[1,-1,-1],[1,1]],
result=array.map(a=>a.map((s=>v=>s+=v)(0));
控制台日志(结果)带有的版本

常量更改=[
[1, 1, 1, -1],
[1, -1, -1],
[1, 1]
];
const values=changes.map(数组=>{
设acc=0;
返回array.map(v=>acc+=v);
});
console.log(值)

.as控制台包装{top:0;max height:100%!important}
生成器的新ESNext功能非常适合这一点

在这里,我创建了一个简单的
sumpUp
生成器,可以重复使用

函数*summap(a){
设和=0;
(a的常数v)的收益和+=v;
}
常量变化=[[1,1,1,-1],[1,-1,-1],[1,1];
const values=changes.map(a=>[…summap(a)];
console.log(值)另一种方式

您可以使用返回具有所需结果的新数组。通过将数组用作累加器,可以生成子数组

var数组=[[1,1,1,-1],[1,-1,-1],[1,1]],
结果=数组.map(a=>a.reduce((ac,v,i)=>{
const lastVal=ac[i-1]| | 0;
返回[…ac,lastVal+v];
}, []));
控制台日志(结果);
//短的
结果=数组.map(a=>a.reduce((ac,v,i)=>[…ac,(ac[i-1]|0)+v],]);

控制台日志(结果)这里有一种更易于阅读的方法,可以遍历外部数组列表。制作内部数组的副本以保留初始值(如[1,1,1,-1])。然后,它迭代复制数组中的每个值,并将其添加到原始数组中该值之后的每个索引中

var变化=[[1,1,1,-1],[1,-1,-1],[1,1]];
changes.forEach(子数组=>{
var subArray copy=subArray.slice();//创建当前子数组的副本(即subArray copy=[1,1,1,-1];)
subrayCopy.forEach((val,index)=>{//遍历副本中的每个值
对于(var i=subArray.length-1;i>index;i--){//从末尾到当前索引的每个元素
子数组[i]+=val;//将副本的当前索引值添加到原始数组中
}
});
})

控制台日志(更改)您有一个数组,但每个组成数组都独立于下一个数组,所以让我们分别处理它们。让我们谈谈
[1,1,1,-1]

你使用的短语“部分和”信息量很大。可以使用
reduce
实现全额合计:

[1,1,1,-1]。减少((x,y)=>x+y);
// 2
但是你需要一个部分和的数组。这与
reduce
的用法非常相似,但我们不仅保留最后的计算结果,还保留了所有中间值。在其他语言中,这称为
scan
(参见)

通用
扫描
的javascript实现可能看起来很像
reduce
。实际上,您可以使用
reduce
实现它,只需做一点额外的工作:

函数扫描(数组、回调){
常量结果=[array[0]];
//reduce为我们完成了所有繁重的工作,但我们定义了一个包装器来传递给它。
array.reduce((…args)=>{
//包装器将所有这些参数转发到回调,但捕获结果。。。
常量结果=回调(…参数);
//…将中间结果存储在结果数组中。。。
结果。推(结果);
//…然后将其传递回reduce以继续它正在执行的操作。
返回结果;
});
返回结果;
}
//扫描([1,1,1,-1],(x,y)=>x+y)->[1,2,3,2]
更健壮的实现将更接近标准库的
reduce
,尤其是在初始值方面:

函数扫描(数组、回调、初始值){
常量结果=[];
常数缩减器=(…参数)=>{
常量结果=回调(…参数);
结果。推(结果);
返回结果;
};
if(arguments.length==2){
结果:push(数组[0]);
数组。还原(还原);
}否则{
结果:推送(初始值);
array.reduce(reducer,initialValue);
}
返回结果;
}
把它放在一起,如果你想为你的数组做这个,它只是一个
map
over
scan

[[1,1,1,-1],[1,-1,-1],[1,1]].map(a=>scan(a,(x,y)=>x+y));
// [[1, 2, 3, 2], [1, 0, -1], [1, 2]]

无需复制或注意副作用,您可以从中获得一个方便的高阶功能来引导

请详细说明“我希望能够基于数组中的下一个值增加值以获得此结果:”这只是一个包装在
.map
中的值。这个方法比你在那里能找到的任何方法都要好。@JollyJoker Thomas simulate
。reduce
方法,为什么不直接使用呢?@Thomas看我的答案,你可以使用数组作为累加器。如果你想产生结果,千万不要使用
forEach
。这会修改源数组,这可能不是一个好主意。是的。而
slice
将有助于防止这种情况。感谢tipThat first方法看起来不错,但实际上效率很低。@T.J.Crowder你能帮我吗