HooneyLog
© 2026 Seunghoon Shin. All rights reserved.
모든 게시글
typescript
2022. 7. 29.•
1

효율적인 데이터 관리를 위한 TypeScript Array Grouping 구현하기

Seunghoon Shin
작성자 Seunghoon Shin풀스택 개발자

효율적인 데이터 관리를 위한 TypeScript Array Grouping 구현하기

1. 문제의 배경

프론트엔드 개발을 하다 보면 서버로부터 받은 방대한 리스트 데이터를 특정 기준(카테고리, 날짜 등)에 따라 분류하여 화면에 보여주어야 할 때가 많습니다. 이때 가장 흔히 사용하는 방식이 Array.prototype.filter() 메서드입니다.

하지만 filter는 호출될 때마다 배열 전체를 순회하므로, 여러 카테고리를 처리하기 위해 filter를 반복해서 사용하면 배열의 크기가 커질수록 성능 부담이 **O(n * k) (n: 배열 크기, k: 카테고리 수)로 선형적으로 증가하게 됩니다. 단순히 특정 카테고리의 데이터를 찾기 위해 매번 전체 배열을 뒤지는 것은 비효율적입니다.

2. 해결 방안 탐색

이 문제를 해결하는 가장 좋은 방법은 데이터를 미리 그룹화(Grouping) 해두는 것입니다. 배열을 단 한 번만 순회하여 객체(Object)나 맵(Map) 형태로 데이터를 재구성해두면, 이후에는 키(Key)를 통해 데이터에 직접 접근할 수 있어 접근 속도가 O(1)로 비약적으로 향상됩니다.

기존의 filter 방식과 groupBy 방식의 성능 차이를 비교해 보겠습니다.

3. 핵심 개념 및 아키텍처

데이터 그룹화의 핵심은 배열을 순회하며 각 아이템의 특정 속성을 키로 사용하는 '해시 맵' 형태의 객체를 만드는 것입니다.

  • Filter 방식: 매번 filter(category === 'X') 실행 -> 전체 순회.
  • GroupBy 방식: 단 한 번 reduce 실행 -> 결과 객체 생성 -> result['X']로 즉시 접근.

4. 구현 및 트러블슈팅

TypeScript의 제네릭을 활용하여 재사용성이 높고 타입 안정성이 보장되는 groupBy 유틸리티 함수를 구현해 보겠습니다.

기본 구현

const DUMMY = [ { category: "food", name: "짜장면" }, { category: "electronic", name: "TV" }, { category: "food", name: "떡볶이" }, { category: "clothes", name: "tshirt" }, ]; /</strong> * 배열을 특정 키를 기준으로 그룹화하는 유틸리티 함수 */ const groupBy = <T extends Record<string, any>>( array: T[], keyForGrouping: keyof T ): Record<string, T[]> => { return array.reduce<Record<string, T[]>>((group, item) => { const valueForGrouping = item[keyForGrouping]; // 그룹이 존재하지 않으면 빈 배열로 초기화 후 아이템 추가 return { ...group, [valueForGrouping]: group[valueForGrouping] ? [...group[valueForGrouping], item] : [item] }; }, {}); }; // 사용 예시 const groupedData = groupBy(DUMMY, 'category'); console.log(groupedData.food); // [{ category: "food", name: "짜장면" }, ...]

구현 시 주의사항 (성능 최적화)

위의 구현에서 ...group (Spread Operator)을 reduce 내부에서 사용하면 매 순회마다 새로운 객체를 생성하므로, 대량의 데이터 처리 시 가비지 컬렉션 부담이 커질 수 있습니다. 실무에서는 다음과 같이 Mutable하게 작성하는 것이 성능상 유리합니다.

const groupByOptimized = <T extends Record<string, any>>( array: T[], keyForGrouping: keyof T ): Record<string, T[]> => { return array.reduce<Record<string, T[]>>((group, item) => { const key = String(item[keyForGrouping]); if (!group[key]) { group[key] = []; } group[key].push(item); return group; }, {}); };

5. 결과 및 Trade-off

정성적 성과

  • 코드 가독성: 데이터 분류 로직이 유틸리티 함수로 추상화되어 비즈니스 로직이 깔끔해집니다.
  • 성능 개선: 대규모 리스트에서 특정 카테고리 데이터를 반복적으로 찾을 때의 지연 시간이 사라집니다.

Trade-off

  • 메모리 사용량: 원본 배열 외에 그룹화된 객체를 추가로 유지해야 하므로 메모리 점유율이 일시적으로 상승할 수 있습니다.
  • 정적 데이터에 적합: 데이터가 실시간으로 빈번하게 추가/변경되는 경우에는 매번 그룹화를 다시 수행해야 하므로 오히려 오버헤드가 발생할 수 있습니다.

6. 마치며

TypeScript의 강력한 타입 시스템과 결합된 groupBy 함수는 데이터 중심의 웹 애플리케이션에서 필수적인 도구입니다. 최근 JavaScript 표준(ES2024)에는 Object.groupBy()와 Map.groupBy()가 공식적으로 추가되었으니, 최신 환경이라면 이를 활용하는 것도 좋은 방법입니다.

참고 자료:

  • MDN: Object.groupBy()
  • TypeScript Generics Documentation
← 이전 글Basic and Useful React Custom Hooks
다음 글 →Facade Pattern