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

자바스크립트(JavaScript)로 객체 배열을 키별로 묶어 하나의 객체로 결합하는 방법

실무에서는 여러 개의 객체가 들어 있는 배열을 하나의 객체로 재구성해야 하는 경우가 종종 있습니다. 예를 들어, 다음과 같이 학생 정보를 담은 객체 배열이 있다고 가정해 보겠습니다.

const arr = [{
    name: 'A',
    idNo: 1,
    marks: {
       math: 98,
       sci: 97,
       eng: 89
    }
},
{
    name: 'B',
    idNo: 2,
    marks: {
       math: 88,
       sci: 87,
       eng: 79
    }
},
{
    name: 'C',
    idNo: 3,
    marks: {
       math: 87,
       sci: 98,
       eng: 91
    }
}];

문제 정의

요구 사항은 이러한 배열을 인수로 받는 자바스크립트 함수를 작성하는 것입니다. 함수는 원본 객체들이 가지고 있는 각 키(name, idNo, marks)마다 하나의 속성을 갖는 새로운 객체를 만들어야 하며, 각 속성의 값에는 기존 객체들의 해당 값들이 순서대로 배열에 담겨 있어야 합니다.

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

const output = {
    name: ['A', 'B', 'C'],
    idNo: [1, 2, 3],
    marks: [{
       math: 98,
       sci: 97,
       eng: 89
    },
    {
       math: 88,
       sci: 87,
       eng: 79
    },
    {
       math: 87,
       sci: 98,
       eng: 91
    }]
};

예제 코드

이 문제는 배열 메서드인 reduce()Object.keys()를 조합하면 깔끔하게 해결할 수 있습니다. 구현 코드는 다음과 같습니다.

const arr = [{
    name: 'A',
    idNo: 1,
    marks: {
       math: 98,
       sci: 97,
       eng: 89
    }
},
{
    name: 'B',
    idNo: 2,
    marks: {
       math: 88,
       sci: 87,
       eng: 79
    }
},
{
    name: 'C',
    idNo: 3,
    marks: {
       math: 87,
       sci: 98,
       eng: 91
    }
}];
const combineMarks = (arr = []) => {
    let res = [];
    res = arr.reduce((acc, val) => {
       Object.keys(val).forEach(el => {
          if (!acc[el]) {
             acc[el] = [];
          };
          acc[el].push(val[el])
       });
       return acc;
    }, {});
    return res;
};
console.log(combineMarks(arr));

코드 동작 원리

  • reduce()는 배열을 처음부터 끝까지 순회하면서 누적 객체(acc)를 점진적으로 채워 나갑니다. 초기값으로 빈 객체 {}를 전달합니다.
  • 순회 중인 각 객체에 대해 Object.keys(val)로 모든 키를 추출하고, forEach()로 하나씩 처리합니다.
  • 현재 키가 누적 객체에 아직 없다면 if (!acc[el]) 조건을 통해 빈 배열로 초기화한 뒤, 해당 키의 값을 push()로 추가합니다.
  • 모든 요소를 순회하고 나면 키별로 값들이 모인 단일 객체가 완성되어 반환됩니다.

출력 결과

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

{
    name: [ 'A', 'B', 'C' ],
    idNo: [ 1, 2, 3 ],
    marks: [
       { math: 98, sci: 97, eng: 89 },
       { math: 88, sci: 87, eng: 79 },
       { math: 87, sci: 98, eng: 91 }
    ]
}

이처럼 reduce()를 활용하면 객체 배열의 구조를 유지하면서도 키를 기준으로 데이터를 손쉽게 재배열할 수 있습니다. 이 패턴은 API 응답 데이터를 그룹화하거나 차트용 데이터셋을 만들 때 특히 유용하게 사용됩니다.