Как составить список частичных сумм с помощью 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[i] + change[i + 1]
});

Я думаю, что я на правильном пути, но я не могу заставить этот подход работать, или, может быть, есть лучший способ сделать это.

Ответы

Ответ 1

Вы можете сохранить сумму и добавить значения.

var array = [[1, 1, 1, -1], [1, -1, -1], [1, 1]],
    result = array.map(a => a.map((s => v => s += v)(0)));

console.log(result);

Ответ 2

Версия с картой.

const changes = [
  [1, 1, 1, -1],
  [1, -1, -1],
  [1, 1]
];

const values = changes.map(array => {
  let acc = 0;
  return array.map(v => acc += v);
});

console.log(values);
.as-console-wrapper{top:0;max-height:100%!important}

Ответ 3

Новые возможности ESNext генераторов хороши для этого.

Здесь я создал простой генератор sumpUp который вы можете использовать повторно.

function* sumUp(a) {
  let sum = 0;
  for (const v of a) yield sum += v;
}

const changes = [ [1, 1, 1, -1], [1, -1, -1], [1, 1] ];
const values = changes.map(a => [...sumUp(a)]);
  
console.log(values);

Ответ 4

Вы можете использовать функцию карты массива

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])))
console.log(changes);
console.log(result);

Ответ 5

const changes = [ [1, 1, 1, -1], [1, -1, -1], [1, 1] ]
let values = []
changes.forEach(arr => {
  let accu = 0
  let nestedArr = []
  arr.forEach(n => {
    accu += n
    nestedArr.push(accu)
  })
  values.push(nestedArr)
})
console.log(values)

Ответ 6

По-другому,

Вы можете использовать .map для возврата вашего нового массива с желаемыми результатами. Используя .reduce с массивом в качестве аккумулятора, вы можете генерировать подмассив.

var array = [[1, 1, 1, -1], [1, -1, -1], [1, 1]],
    result = array.map(a => a.reduce((ac, v, i) => {
      const lastVal = ac[i-1] || 0;
      return [...ac, lastVal + v];
    }, []));

console.log(result);

// shorter
result = array.map(a => a.reduce((ac, v, i) => [...ac, (ac[i-1] || 0) + v], []));
console.log(result);

Ответ 7

Вот более легкий для чтения способ, который перебирает внешний список массивов. Копия внутреннего массива делается для сохранения начальных значений (например, [1, 1, 1, -1]). Затем он перебирает каждое значение в скопированном массиве и добавляет его к каждому индексу после исходного массива.

var changes = [[1, 1, 1, -1], [1, -1, -1], [1, 1]];
changes.forEach(subArray => {
    var subArrayCopy = subArray.slice(); 	// Create a copy of the current sub array (i.e. subArrayCopy = [1, 1, 1, -1];)
    subArrayCopy.forEach((val, index) => {	// Iterate through each value in the copy
	for (var i = subArray.length - 1; i > index; i--) { // For each element from the end to the current index
            subArray[i] += val;	 // Add the copy current index value to the original array
	}
    });
})
console.log(changes);