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

JavaScript에서 '_id' 키 값이 동일한 객체들을 그룹화하는 방법

다음과 같이 여러 개의 객체를 담고 있는 배열이 있다고 가정해 보겠습니다.

const arr = [
    {_id : "1", S : "2"},
    {_id : "1", M : "4"},
    {_id : "2", M : "1"},
    {_id : "6" , M : "1"},
    {_id : "3", S : "3"}
];

우리가 작성해야 할 함수는 이러한 배열을 입력받아 '_id' 키의 값이 서로 같은 객체들을 하나로 묶어주는 역할을 합니다. 단순히 묶기만 하는 것이 아니라, 각 그룹 내에서 '_id'를 제외한 나머지 속성(M, S)의 값들은 모두 합산해야 하며, 그 총합을 담은 total 속성도 함께 만들어 주어야 합니다.

따라서 최종적으로 얻어야 하는 결과는 다음과 같은 형태입니다.

const output = [
    {_id : "1", M : 4, S : 2, total: 6},
    {_id : "2", M : 1, S : 0, total: 1},
    {_id : "6", M : 1, S : 0, total: 1},
    {_id : "3", M : 0, S : 3, total: 3}
];

구현 예제

이를 구현한 전체 코드는 다음과 같습니다.

const arr = [
    {_id : "1", S : "2"},
    {_id : "1", M : "4"},
    {_id : "2", M : "1"},
    {_id : "6" , M : "1"},
    {_id : "3", S : "3"}
];
const pickAllConstraints = arr => {
    let constraints = [];
    arr.forEach(el => {
       const keys = Object.keys(el);
       constraints = [...constraints, ...keys];
    });
    return constraints.filter((el, ind) => el !== '_id' && ind === constraints.lastIndexOf(el));
};
const buildItem = (cons, el = {}, prev = {}) => {
    const item = {};
    let total = 0
    cons.forEach(i => {
       item[i] = (+el[i] || 0) + (+prev[i] || 0);
       total += item[i];
    });
    item.total = total;
    return item;
}
const buildCumulativeArray = arr => {
    const constraints = pickAllConstraints(arr);
    const map = {}, res = [];
    arr.forEach(el => {
       const { _id } = el;
       if(map.hasOwnProperty(_id)){
          res[map[_id] - 1] = {
             _id, ...buildItem(constraints, el, res[map[_id] - 1])
          };
       }else{
          map[_id] = res.push({
             _id, ...buildItem(constraints, el)
          });
       }
    });
    return res;
};
console.log(buildCumulativeArray(arr));

실행 결과

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

[
    { _id: '1', M: 4, S: 2, total: 6 },
    { _id: '2', M: 1, S: 0, total: 1 },
    { _id: '6', M: 1, S: 0, total: 1 },
    { _id: '3', M: 0, S: 3, total: 3 }
]

코드 동작 원리

이 코드는 세 개의 함수로 구성되어 있으며, 각각 다음과 같은 역할을 담당합니다.

1. pickAllConstraints – 집계 대상 키 추출

배열의 모든 객체에서 키 이름을 수집한 뒤 중복을 제거하고, '_id'는 제외합니다. 이 예제에서는 ['M', 'S']라는 목록이 만들어집니다. 키를 미리 추출해 두면 어떤 속성 조합이 들어오더라도 유연하게 대응할 수 있다는 장점이 있습니다.

2. buildItem – 값 누적 처리

현재 객체(el)와 이전까지 누적된 객체(prev)를 받아 각 키별로 값을 더합니다. (+el[i] || 0) 패턴을 사용하면 해당 키가 존재하지 않거나 값이 문자열이더라도 안전하게 숫자 0으로 처리할 수 있습니다. 마지막에는 모든 키 값을 합산한 total을 계산해 함께 반환합니다.

3. buildCumulativeArray – 그룹화 및 병합

map 객체에 각 _id가 처음 등장했을 때의 인덱스를 기록해 둡니다. 같은 _id를 가진 객체가 다시 나타나면 새 항목을 추가하는 대신, 기존 항목 위에 buildItem의 누적 결과를 덮어써서 하나의 객체로 병합합니다. 이 과정을 거치면 _id별로 속성 값이 합산된 최종 배열이 완성됩니다.

참고로 입력 데이터에서 속성 값이 문자열("4") 형태로 되어 있어도 + 연산자를 통해 숫자로 변환되기 때문에, 실행 결과의 값들은 숫자(4, 2, 6 등)로 출력됩니다.