JavaScript 개발을 하다 보면 객체 배열에서 특정 속성 값을 기준으로 데이터를 그룹화하고, 각 값이 몇 번 반복되었는지(중복 횟수) 계산해야 하는 경우가 자주 발생합니다. 이 글에서는 이러한 작업을 효율적으로 처리하는 알고리즘을 단계별로 살펴보겠습니다.
문제 정의
객체로 구성된 배열이 있다고 가정해 보겠습니다. 한 객체의 특정 속성이 다른 객체의 속성과 동일하다면, 우리는 이를 중복 항목으로 간주합니다.
예를 들어 다음과 같은 데이터가 있습니다.
X A B O Y X Z I Y X Z U X A B L Y X Z K
여기서 첫 번째 값을 기준으로 그룹화하려고 합니다. 나머지 두 속성 역시 각 중복 항목 안에서 서로 같지만, 첫 번째 값만 비교하면 충분합니다.
최종적으로 사용자에게 표시할 결과는 다음과 같은 형태가 됩니다.
Y X Z (3) X A B (2)
즉, 'Y X Z' 조합은 3번, 'X A B' 조합은 2번 등장했다는 의미입니다.
구현 예제 코드
이 문제를 해결하는 JavaScript 코드는 다음과 같습니다.
const arr = [
{x: 'x', acc: 'acc', val: 'val'},
{y: 'y', x: 'x', z: 'z'},
{y: 'y', x: 'x', z: 'z'},
{x: 'x', c: 'c', val: 'val'}
];
const countOccurrence = (arr = []) => {
const res = {};
arr.forEach(item => {
Object.keys(item).forEach(prop => {
(res[prop]) ? res[prop] += 1 : res[prop] = 1;
});
});
return res;
}
const groupByOccurrence = (data = []) => {
const obj = countOccurrence(data);
const res = Object.keys(obj).reduce((acc, val) => {
(acc[obj[val]]) ? acc[obj[val]].push(val) : acc[obj[val]] = [val];
return acc;
}, {});
return res;
}
console.log(groupByOccurrence(arr));
코드 동작 원리
countOccurrence 함수: 배열의 각 객체를 순회하면서 객체가 가진 모든 속성 이름(key)의 등장 횟수를 집계합니다. 그 결과는 속성 이름을 키로, 등장 횟수를 값으로 갖는 객체입니다.
groupByOccurrence 함수: countOccurrence의 결과를 받아, 등장 횟수별로 속성 이름들을 묶습니다. reduce 메서드를 활용해 등장 횟수를 기준으로 그룹화된 새로운 객체를 생성합니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
{ '1': [ 'acc', 'c' ], '2': [ 'val', 'y', 'z' ], '4': [ 'x' ] }
결과를 해석해 보면 다음과 같습니다.
- 'acc'와 'c'는 각각 1번 등장했습니다.
- 'val', 'y', 'z'는 각각 2번 등장했습니다.
- 'x'는 4번 등장했습니다.
이처럼 일반 객체와 함께 forEach, reduce 같은 배열 메서드를 적절히 활용하면 복잡해 보이는 그룹화 및 빈도 계산 작업도 간결하고 효율적으로 처리할 수 있습니다. 실무에서는 로그 분석, 태그 카운트, 통계 집계 등 다양한 상황에서 응용할 수 있는 패턴이니 꼭 기억해 두시기 바랍니다.