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

JavaScript에서 중첩 배열을 type 속성 기준으로 그룹화하는 방법


문제 소개

다음과 같이 값들이 담긴 배열이 있다고 가정해 보겠습니다.

const arr = [
  {
    value1:[1,2],
    value2:[{type:'A'}, {type:'B'}]
  },
  {
    value1:[3,5],
    value2:[{type:'B'}, {type:'B'}]
  }
];

배열의 각 요소는 두 개의 속성을 가진 객체입니다. value1은 숫자 배열이며, value2type 속성을 가진 객체들의 배열입니다. 우리가 작성해야 할 JavaScript 함수는 이러한 배열을 입력으로 받아, 객체의 "type" 속성을 기준으로 데이터를 그룹화한 새로운 배열을 반환하는 역할을 합니다.

따라서 위 배열에 대한 최종 출력은 다음과 같은 형태가 됩니다.

const output = [
  {type:'A', value: [1,2]},
  {type:'B', value: [3,5]}
];

예제 코드

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

const arr = [
  {
    value1:[1,2],
    value2:[{type:'A'}, {type:'B'}]
  },
  {
    value1:[3,5],
    value2:[{type:'B'}, {type:'B'}]
  }
];
const groupValues = (arr = []) => {
  const res = [];
  arr.forEach((el, ind) => {
    const thisObj = this;
    el.value2.forEach(element => {
      if (!thisObj[element.type]) {
        thisObj[element.type] = {
          type: element.type,
          value: []
        }
        res.push(thisObj[element.type]);
      };
      if (!thisObj[ind + '|' + element.type]) {
        thisObj[element.type].value =
        thisObj[element.type].value.concat(el.value1);
        thisObj[ind + '|' + element.type] = true;
      };
    });
  }, {})
  return res;
};
console.log(groupValues(arr));

코드 동작 원리

  • 외부 순회: forEach()를 사용해 입력 배열의 각 객체를 하나씩 순회합니다.
  • 그룹 추적: 빈 객체({})를 thisArg로 전달하여, 이미 생성된 type 그룹을 키로 저장함으로써 중복 생성을 방지합니다.
  • 그룹 생성: value2의 각 요소를 확인하여 해당 type의 그룹이 아직 없으면 새로 만들고, 결과 배열 res에 추가합니다.
  • 중복 병합 방지: 인덱스|type 형태의 키를 활용해, 같은 객체 안에서 동일한 type이 여러 번 등장하더라도 value1이 한 번만 병합되도록 처리합니다.
  • 값 병합: concat() 메서드로 value1의 값들을 해당 그룹의 value 배열에 누적합니다.

출력 결과

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

[
  { type: 'A', value: [ 1, 2 ] },
  { type: 'B', value: [ 1, 2, 3, 5 ] }
]

여기서 주목할 점은 첫 번째 객체의 value2에도 type 'B'가 포함되어 있다는 것입니다. 따라서 B 그룹에는 첫 번째 객체의 값([1, 2])과 두 번째 객체의 값([3, 5])이 모두 병합되어 [1, 2, 3, 5]가 됩니다. 반면 type 'A'는 첫 번째 객체에만 존재하므로 [1, 2]만 담게 됩니다.