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

JavaScript로 중첩 배열을 객체 배열로 변환하는 방법

JavaScript를 다루다 보면 중첩된 배열 구조의 데이터를 객체 형태로 변환해야 하는 경우가 자주 발생합니다. 이 글에서는 배열 안에 배열이 포함된 복잡한 구조를 깔끔한 객체 배열로 바꾸는 방법을 알아보겠습니다.

문제 상황

다음과 같이 배열 안에 배열이 중첩된 데이터가 있다고 가정해 보겠습니다.

const arr = [
    [
        ['dog', 'Harry'], ['age', 2]
    ],
    [
        ['dog', 'Roger'], ['age', 5]
    ]
];

각 내부 배열은 [키, 값] 쌍으로 이루어져 있습니다. 우리는 이러한 중첩 배열을 입력받아 아래와 같은 객체 배열로 변환하는 함수를 작성해야 합니다.

const output = [
    {dog: 'Harry', age: 2},
    {dog: 'Roger', age: 5}
];

해결 방법

핵심 아이디어는 각 내부 배열을 순회하면서 키-값 쌍을 하나의 객체로 묶는 것입니다. 다음 코드를 살펴보겠습니다.

const arr = [
    [
        ['dog', 'Harry'], ['age', 2]
    ],
    [
        ['dog', 'Roger'], ['age', 5]
    ]
];
const prepareObjectArray = (arr = []) => {
    const copy = arr.slice();
    copy.forEach((el, ind, array) => {
        el.forEach((element, index, subArray) => {
            subArray[element[0]] = element[1];
        });
        el.length = 0;
        array[ind] = Object.assign({}, array[ind]);
    });
    return copy;
};
console.log(prepareObjectArray(arr));

코드 동작 원리

이 코드가 어떻게 동작하는지 단계별로 살펴보겠습니다.

1. 원본 배열 보호: arr.slice()를 사용해 원본 배열의 얕은 복사본을 만듭니다. 이렇게 하면 변환 과정에서 원본 데이터가 손상되지 않습니다.

2. 키-값 할당: 각 내부 배열을 순회하면서 subArray[element[0]] = element[1] 구문으로 배열에 동적으로 프로퍼티를 추가합니다. 예를 들어 ['dog', 'Harry']subArray.dog = 'Harry'가 됩니다.

3. 배열 요소 제거: el.length = 0을 실행하여 배열의 인덱스 요소들을 모두 제거하고, 객체 프로퍼티만 남깁니다.

4. 객체 변환: Object.assign({}, array[ind])를 통해 프로퍼티만 담긴 새로운 순수 객체를 생성하여 기존 위치에 할당합니다.

실행 결과

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

[ { dog: 'Harry', age: 2 }, { dog: 'Roger', age: 5 } ]

더 간결한 대안: Object.fromEntries 활용

모던 JavaScript(ES2019 이상)에서는 Object.fromEntries()를 사용하면 훨씬 직관적으로 같은 결과를 얻을 수 있습니다.

const prepareObjectArray = (arr = []) =>
    arr.map(subArr => Object.fromEntries(subArr));

console.log(prepareObjectArray(arr));
// [ { dog: 'Harry', age: 2 }, { dog: 'Roger', age: 5 } ]

Object.fromEntries()는 키-값 쌍의 목록을 받아 하나의 객체로 변환해 주기 때문에, 위에서 살펴본 복잡한 수동 처리 과정 없이 한 줄로 해결됩니다. 최신 환경에서 개발한다면 이 방법을 권장합니다.

마무리

중첩 배열을 객체로 변환하는 작업은 API 응답 데이터 가공, 설정 파일 파싱 등 실무에서 매우 유용하게 활용됩니다. 전통적인 forEach 기반 접근법과 모던한 Object.fromEntries() 방식을 모두 이해해 두면 다양한 상황에 유연하게 대처할 수 있습니다.