이번 글에서는 숫자 배열을 요소로 갖는 2차원 배열을 입력받아, 각 하위 배열에 대해 부분 합계(partial sum) 배열을 만드는 JavaScript 함수를 작성해 보겠습니다.
부분 합계란?
부분 합계 배열이란, 특정 위치의 값이 자기 자신과 그 이전 값들을 모두 더한 누적 합으로 대체된 배열을 의미합니다. 즉, 각 요소는 현재 값과 앞선 모든 값의 합계가 됩니다.
예시
입력 배열이 다음과 같다고 가정해 보겠습니다.
const arr = [ [1, 1, 1, -1], [1, -1, -1], [1, 1] ];
이 경우 기대되는 출력 결과는 다음과 같습니다.
const output = [ [1, 2, 3, 2], [1, 0, -1], [1, 2] ];
첫 번째 하위 배열 [1, 1, 1, -1]을 살펴보면, 첫 번째 값은 1, 두 번째 값은 1+1=2, 세 번째 값은 1+1+1=3, 네 번째 값은 1+1+1+(-1)=2가 되는 방식입니다.
구현 코드
이 문제는 forEach() 메서드와 누적 변수(accu)를 활용하면 간단하게 해결할 수 있습니다. 바깥쪽 반복문으로 각 하위 배열을 순회하고, 안쪽 반복문에서 각 요소를 누적 변수에 더한 뒤 결과 배열에 추가하는 방식입니다.
const arr = [
[1, 1, 1, -1],
[1, -1, -1],
[1, 1]
];
const partialSum = (arr = []) => {
const res = [];
arr.forEach(sub => {
let accu = 0;
const nestedArr = [];
sub.forEach(n => {
accu += n;
nestedArr.push(accu);
});
res.push(nestedArr);
});
return res;
};
console.log(partialSum(arr));코드 설명
res: 최종 결과를 담을 배열입니다.arr.forEach(sub => ...): 입력받은 2차원 배열의 각 하위 배열을 순회합니다.accu: 각 하위 배열마다 초기화되어(0으로 설정), 요소들의 누적 합을 저장합니다.nestedArr: 현재 하위 배열의 부분 합계 값을 저장하는 임시 배열입니다.- 모든 요소를 처리한 후
nestedArr를res에 추가하고, 최종적으로res를 반환합니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 출력이 표시됩니다.
[ [ 1, 2, 3, 2 ], [ 1, 0, -1 ], [ 1, 2 ] ]
추가 팁: map과 reduce 활용하기
함수형 프로그래밍 스타일을 선호한다면 map()과 reduce()를 조합하여 더 간결하게 작성할 수도 있습니다.
const partialSum = (arr = []) => arr.map(sub => sub.reduce((acc, n) => [...acc, (acc[acc.length - 1] ?? 0) + n], []));
두 방식 모두 동일한 결과를 반환하지만, forEach를 사용한 첫 번째 방식이 코드 흐름을 이해하기에는 더 직관적일 수 있습니다. 상황과 팀의 코딩 스타일에 맞게 선택하시면 됩니다.