Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

자바스크립트로 중첩 배열의 같은 인덱스 요소를 합산하여 단일 배열 만들기

배열 안에 여러 개의 배열이 들어 있는 중첩 배열(nested array)이 있을 때, 이 배열을 입력받아 원본 배열들의 같은 인덱스에 있는 요소들의 합으로 이루어진 새로운 배열을 반환하는 함수를 작성해야 하는 경우가 있습니다.

문제 예시

원본 배열이 다음과 같다고 가정해 보겠습니다.

[
    [43, 2, 21],
    [1, 2, 4, 54],
    [5, 84, 2],
    [11, 5, 3, 1]
]

각 하위 배열의 첫 번째 요소끼리(43 + 1 + 5 + 11 = 60), 두 번째 요소끼리(2 + 2 + 84 + 5 = 93) 식으로 더하므로, 기대하는 출력 결과는 다음과 같습니다.

[60, 93, 30, 55]

해결 방법: sumArray() 함수 작성하기

이 문제는 각 하위 배열을 순회하면서 인덱스별로 값을 누적하는 방식으로 해결할 수 있습니다. 전체 코드는 다음과 같습니다.

const arr = [
    [43, 2, 21],
    [1, 2, 4, 54],
    [5, 84, 2],
    [11, 5, 3, 1]
];

const sumArray = (array) => {
    const newArray = [];
    array.forEach(sub => {
        sub.forEach((num, index) => {
            if (newArray[index]) {
                newArray[index] += num;
            } else {
                newArray[index] = num;
            }
        });
    });
    return newArray;
}

console.log(sumArray(arr));

실행 결과

콘솔에 출력되는 결과는 다음과 같습니다.

[ 60, 93, 30, 55 ]

코드 동작 원리

위 코드의 작동 방식은 다음과 같습니다.

먼저 결과를 담을 빈 배열 newArray를 생성합니다. 그다음 외부의 forEach로 원본 배열의 각 하위 배열을 순회하고, 내부의 forEach로 하위 배열의 각 숫자와 해당 인덱스를 가져옵니다.

이때 newArray[index]에 이미 값이 존재하면 해당 값에 현재 숫자를 더해 누적하고, 존재하지 않으면 현재 숫자를 그대로 할당합니다. 모든 순회가 끝나면 인덱스별 합계가 저장된 새로운 배열을 반환합니다.

reduce를 활용한 대안

조금 더 간결하게 작성하고 싶다면 reduce 메서드를 활용할 수도 있습니다.

const sumArray = (array) =>
    array.reduce((acc, sub) =>
        sub.map((num, index) => (acc[index] || 0) + num), []);

console.log(sumArray(arr)); // [ 60, 93, 30, 55 ]

두 방법 모두 하위 배열의 길이가 서로 달라도 정상적으로 동작하며, 짧은 배열에 없는 인덱스는 긴 배열의 값만 반영됩니다. 상황에 맞는 방식을 선택해 사용하면 됩니다.