JavaScript 개발을 하다 보면 키-값 쌍으로 이루어진 중첩 배열을 객체 배열로 변환해야 하는 경우가 자주 발생합니다. 이럴 때 map()과 reduce() 메서드를 함께 사용하면 간결하고 우아하게 문제를 해결할 수 있습니다.
문제 상황
다음과 같이 배열 안에 배열이 중첩된 형태의 데이터가 있다고 가정해 보겠습니다.
const arr = [
[
['juice', 'apple'], ['maker', 'motts'], ['price', 12]
],
[
['juice', 'orange'], ['maker', 'sunkist'], ['price', 11]
]
];우리는 이러한 배열을 입력받아, 각 내부 배열의 키-값 쌍을 속성으로 가지는 객체들로 구성된 새로운 배열을 반환하는 함수를 작성해야 합니다. 즉, 위 배열에 대한 결과물은 다음과 같은 형태가 되어야 합니다.
const output = [
{juice: 'apple', maker: 'motts', price: 12},
{juice: 'orange', maker: 'sunkist', price: 11}
];해결 접근 방식
이 문제는 두 단계로 나누어 생각할 수 있습니다.
- map(): 외부 배열의 각 요소(내부 배열)를 하나의 객체로 변환합니다.
- reduce(): 각 내부 배열을 순회하면서 [키, 값] 쌍을 하나의 객체로 누적 병합합니다.
코드 구현
이를 구현한 코드는 다음과 같습니다.
const arr = [
[
['juice', 'apple'], ['maker', 'motts'], ['price', 12]
],
[
['juice', 'orange'], ['maker', 'sunkist'], ['price', 11]
]
];
const arrayToObject = arr => {
return arr.map(list => {
return list.reduce((acc, val) => {
acc[val[0]] = val[1];
return acc;
}, {});
});
};
console.log(arrayToObject(arr));출력 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[
{ juice: 'apple', maker: 'motts', price: 12 },
{ juice: 'orange', maker: 'sunkist', price: 11 }
]동작 원리 살펴보기
map()은 외부 배열 arr의 각 요소, 즉 [['juice', 'apple'], ['maker', 'motts'], ['price', 12]]와 같은 내부 배열을 순차적으로 처리합니다. 각 내부 배열에 대해 reduce()를 호출할 때 초기값으로 빈 객체 {}를 전달합니다.
reduce() 내부에서는 각 쌍 val의 첫 번째 요소(val[0])를 키로, 두 번째 요소(val[1])를 값으로 사용하여 누적 객체 acc에 할당합니다. 예를 들어 ['juice', 'apple']이라는 쌍은 acc.juice = 'apple'로 처리됩니다.
모든 쌍이 처리되면 완성된 객체가 반환되고, 최종적으로 map()은 이렇게 변환된 객체들을 모아 새로운 배열로 반환합니다. 이 패턴은 API 응답 데이터 정규화나 CSV 파싱 결과 변환 등 실무에서도 유용하게 활용할 수 있습니다.