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

JavaScript 배열 데이터를 객체로 그룹화하는 방법 (reduce 활용)

문제 정의

다음과 같이 학생들의 과목별 점수가 담긴 2차원 배열이 있다고 가정해 보겠습니다.

const arr = [
  ["English", 52],
  ["Hindi", 154],
  ["Hindi", 241],
  ["Spanish", 10],
  ["French", 65],
  ["German", 98],
  ["Russian", 10]
];

여기서 해야 할 일은 이러한 배열을 입력받아 객체의 객체(object of objects) 형태로 반환하는 JavaScript 함수를 작성하는 것입니다.

반환되는 객체는 각 고유한 과목마다 하나의 하위 객체를 가져야 하며, 각 하위 객체에는 다음 세 가지 정보가 포함되어야 합니다.

  • count: 해당 과목이 배열에 등장한 횟수
  • total: 해당 과목 점수의 총합
  • average: 해당 과목 점수의 평균

구현 코드

배열의 내장 메서드인 reduce()를 사용하면 별도의 반복문 없이도 간결하게 그룹화 로직을 구현할 수 있습니다.

const arr = [
  ["English", 52],
  ["Hindi", 154],
  ["Hindi", 241],
  ["Spanish", 10],
  ["French", 65],
  ["German", 98],
  ["Russian", 10]
];

const groupSubjects = arr => {
  const grouped = arr.reduce((acc, val) => {
    const [key, total] = val;

    // 아직 없는 과목이라면 초기 객체 생성
    if (!Object.prototype.hasOwnProperty.call(acc, key)) {
      acc[key] = { count: 0, total: 0 };
    }

    const subject = acc[key];
    subject.count++;                                  // 등장 횟수 증가
    subject.total += total;                           // 점수 누적
    subject.average = subject.total / subject.count;  // 평균 계산

    return acc;
  }, {});

  return grouped;
};

console.log(groupSubjects(arr));

코드 동작 원리

  1. reduce()의 초기 누적값으로 빈 객체 {}를 지정합니다.
  2. 순회 중인 항목에서 과목명(key)과 점수(total)를 구조 분해 할당으로 추출합니다.
  3. hasOwnProperty()로 해당 과목이 누적 객체에 존재하지 않으면 counttotal이 0인 초기 객체를 생성합니다.
  4. 항목을 처리할 때마다 count를 1 증가시키고 total에 점수를 더합니다.
  5. 평균은 누적된 총합을 등장 횟수로 나눈 값으로 매번 갱신합니다.

주의: 평균을 계산할 때는 현재 항목의 점수가 아니라 반드시 누적된 subject.total을 사용해야 합니다. 그렇지 않으면 마지막에 처리된 항목의 점수를 기준으로 잘못된 평균이 계산됩니다.

실행 결과

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

{
  English: { count: 1, total: 52, average: 52 },
  Hindi: { count: 2, total: 395, average: 197.5 },
  Spanish: { count: 1, total: 10, average: 10 },
  French: { count: 1, total: 65, average: 65 },
  German: { count: 1, total: 98, average: 98 },
  Russian: { count: 1, total: 10, average: 10 }
}

"Hindi"는 두 번 등장했으므로 count는 2, total은 154 + 241 = 395, 평균은 395 ÷ 2 = 197.5로 올바르게 계산된 것을 확인할 수 있습니다. 이처럼 reduce() 하나만으로 배열 데이터를 원하는 기준별로 손쉽게 그룹화하고 통계까지 산출할 수 있습니다.