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

JavaScript로 두 개의 배열을 하나로 합치는 방법 – 월별 현금 흐름 데이터 병합하기

JavaScript에서 데이터를 다루다 보면 서로 다른 형태의 배열을 하나로 합쳐야 하는 경우가 자주 발생합니다. 이번 글에서는 월(month) 배열현금 흐름(cashflow) 객체 배열을 결합하여, 모든 월에 대한 데이터를 빠짐없이 포함하는 새로운 배열을 만드는 방법을 알아보겠습니다.

문제 상황

예를 들어, 다음과 같이 현금 흐름을 나타내는 두 개의 배열이 있다고 가정해 보겠습니다.

const months = ["jan", "feb", "mar", "apr"];
const cashflows = [
    {'month':'jan', 'value':10},
    {'month':'mar', 'value':20}
];

여기서 요구되는 것은 이 두 배열을 인자로 받아, 모든 월에 해당하는 객체를 포함하는 하나의 배열을 만드는 JavaScript 함수를 작성하는 것입니다. 만약 특정 월에 대한 현금 흐름 값이 없다면 빈 문자열('')로 채워 넣으면 됩니다.

따라서 위 배열에 대한 최종 출력 결과는 다음과 같은 형태가 되어야 합니다.

const output = [
    {'month':'jan', 'value':10},
    {'month':'feb', 'value':''},
    {'month':'mar', 'value':20},
    {'month':'apr', 'value':''}
];

해결 방법: map과 reduce 활용하기

이 문제는 reduce()로 cashflows 배열을 월 이름을 키로 하는 조회용 객체(lookup table)로 변환한 뒤, map()으로 months 배열을 순회하며 값을 매칭하는 방식으로 깔끔하게 해결할 수 있습니다.

const months = ["jan", "feb", "mar", "apr"];
const cashflows = [
    {'month':'jan', 'value':10},
    {'month':'mar', 'value':20}
];
const combineArrays = (months = [], cashflows = []) => {
    let res = [];
    res = months.map(function(month) {
        return this[month] || { month: month, value: '' };
    }, cashflows.reduce((acc, val) => {
        acc[val.month] = val;
        return acc;
    }, Object.create(null)));
    return res;
};
console.log(combineArrays(months, cashflows));

코드 동작 원리

이 코드의 핵심 로직을 단계별로 살펴보면 다음과 같습니다.

1단계 – reduce()로 조회 테이블 생성: cashflows.reduce()는 각 객체의 month 값을 키로 사용하는 객체를 만듭니다. 결과적으로 { jan: {...}, mar: {...} } 형태의 객체가 생성되어 map()의 두 번째 인자인 thisArg로 전달됩니다.

2단계 – map()으로 월별 데이터 매칭: months.map() 내부에서 this[month]를 통해 해당 월의 데이터를 조회합니다. 값이 존재하면 그 객체를 그대로 반환하고, 존재하지 않으면 { month: month, value: '' } 형태의 기본 객체를 대신 반환합니다.

참고: 초기값으로 일반 객체({}) 대신 Object.create(null)을 사용하면 프로토타입 체인이 없는 순수한 객체가 생성되므로, 'constructor''toString' 같은 내장 속성 이름과의 충돌을 예방할 수 있습니다.

실행 결과

위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.

[
    { month: 'jan', value: 10 },
    { month: 'feb', value: '' },
    { month: 'mar', value: 20 },
    { month: 'apr', value: '' }
]

마무리

이처럼 map()reduce()를 조합하면 두 배열을 기준(key)에 맞춰 손쉽게 병합할 수 있습니다. 이 패턴은 월별 데이터뿐만 아니라 날짜별 매출, 카테고리별 집계 등 기준 배열에는 있지만 실제 데이터 배열에는 누락된 항목을 기본값으로 채워야 하는 다양한 상황에서 널리 활용할 수 있습니다. 성능 면에서도 reduce로 만든 조회 테이블 덕분에 각 월을 O(1) 시간에 찾을 수 있어, 데이터 양이 많아져도 효율적으로 동작한다는 장점이 있습니다.