Object.groupBy / Map.groupBy (ES2024)
๐ Overview
Object.groupBy, Map.groupBy ๋ฌธ๋ฒ์ ํตํด ์ด์ reduce, lodash.groupBy ๊ฐ์ ๋ฐ๋ณต ํจํด ์์ด๋ ํ์ค ๋ฌธ๋ฒ์ผ๋ก ๊น๋ํ๊ฒ ๋ฐ์ดํฐ ๊ทธ๋ฃนํ์ด ๊ฐ๋ฅํ๋ค.
ES2024 ๋ถํฐ ํฌํจ๋ groupBy ๋ฌธ๋ฒ์ ๊ฐ๋
, ์ฐจ์ด์ , ๊ทธ๋ฆฌ๊ณ ์ค๋ฌด์์ ์ ์ฉํ ํ์ฉ๋ฒ์ ์ ๋ฆฌํด๋ณธ๋ค.
1. groupBy ๋ฌธ๋ฒ์ ์ธ์ ๋ถํฐ ์๊ฒผ๋?
ํด๋น ๋ฌธ๋ฒ์ Array Grouping Proposal์ด 2023๋ ๋ง TC39 Stage 4์ ๋๋ฌํ๋ฉด์, ECMAScript 2024 (ES15) ํ์ค์ ์ ์ ํฌํจ๋์๋ค.
| ๊ตฌ๋ถ | ๋ช ์ธ | ๋ด์ฉ |
|---|---|---|
| ์ ์ ๋จ๊ณ | TC39 Stage 4 | Array Grouping Proposal |
| ํ์ค ๋ฐ์ | ECMAScript 2024 | ์ ์ ๋ฌธ๋ฒ ํฌํจ |
| ์ง์ ํ๊ฒฝ | Node 21+, ์ต์ ๋ธ๋ผ์ฐ์ | ๊ธฐ๋ณธ ์ง์ |
๐ก ์ฐธ๊ณ : TC39 Proposal: Array Grouping / MDN Object.groupBy
2. Object vs Map, ์ธ์ ์ด๋ค ๊ฑธ ์จ์ผ ํ ๊น?
groupBy๋ ๋์ผํ ์ธํฐํ์ด์ค์ฒ๋ผ ๋ณด์ด์ง๋ง ๋ฐํ ํ์
์ด ๋ค๋ฅด๋ค. ํ๋๋ Object, ๋ค๋ฅธ ํ๋๋ Map์ ๋ฐํํ๋ฉฐ, ์ด ์ฐจ์ด๊ฐ ์ฌ์ฉ ๋ชฉ์ ์ ์์ ํ ๊ฐ๋ผ๋๋๋ค. ์ผ๋ฐ์ ์ผ๋ก๋ ์ด๋ ๊ฒ ๊ธฐ์ตํ๋ฉด ๋๋ค.
| ์ํฉ | ์ถ์ฒ |
|---|---|
| ๋ฌธ์์ด / JSON ์๋ต ์ค์ฌ | Object.groupBy |
| ์ซ์ / Date / ๊ฐ์ฒด ํค ์ฌ์ฉ | Map.groupBy |
| ํ์ ์ ๋ ฌ / Map API ํ์ฉ | Map.groupBy |
| ์ง๋ ฌํ / ๋จ์ ์๋ต ๊ฐ๊ณต | Object.groupBy |
2-1. Object.groupBy
-
๋ฌธ์์ด / ์ฌ๋ณผ ํค๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ทธ๋ฃนํ
-
๊ฒฐ๊ณผ๊ฐ ์ผ๋ฐ ๊ฐ์ฒด(
Record<string, T[]>)๋ก ๋ฐํ๋์ด JSON ์ง๋ ฌํ๋ API ์๋ต ๊ฐ๊ณต์ ์ ํฉconst orders = [ { id: 'A1', status: 'progress' }, { id: 'A2', status: 'pending' }, { id: 'A3', status: 'failed' }, { id: 'A4', status: 'progress' }, ]; const groupByStatus = Object.groupBy(orders, order => order.status); console.log(groupByStatus); /* { progress: [{id:'A1'}, {id:'A4'}], pending: [{id:'A2'}], failed: [{id:'A3'}] } */
2-2. Map.groupBy
-
๋น๋ฌธ์์ด ํค(์ซ์, Date, ๊ฐ์ฒด ๋ฑ) ๊ทธ๋๋ก ์ฌ์ฉ ๊ฐ๋ฅ
-
๊ฒฐ๊ณผ๊ฐ Map์ผ๋ก ๋ฐํ๋์ด, ์ ๋ ฌ, ๋ณํฉ, ํ์ ์ฐ์ฐ์ ์ ๋ฆฌ
const users = [ { user: 'u1', createdAt: new Date('2025-11-01T10:00Z') }, { user: 'u2', createdAt: new Date('2025-11-01T11:00Z') }, { user: 'u3', createdAt: new Date('2025-11-02T09:00Z') }, ]; const groupByDay = Map.groupBy(users, user => user.createdAt.toDateString()); console.log([...groupByDay.entries()]); // [['Sat Nov 01 2025', [u1,u2]], ['Sun Nov 02 2025', [u3]]]
3. reduce ํจํด๊ณผ ๋น๊ต
์ด์ ์๋ ์ด๋ฐ ์์ผ๋ก reduce๋ฅผ ํ์ฉํ๋ค.
const grouped = orders.reduce((acc, order) => {
(acc[order.status] ??= []).push(order);
return acc;
}, {});์ด์ ๋ ํจ์ฌ ๋จ์ํ๊ฒ ์ธ ์ ์๋ค.
const grouped = Object.groupBy(orders, order => order.status);๐ก ์ฝ๋ ์์ด ์ค์์ ๋ฟ ์๋๋ผ, ์๋๊ฐ ๋ช ํํ๊ฒ ๋๋ฌ๋๋ค. โ๋๋ ์ง๊ธ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ฃนํํ๋ค.โ
4. ES2024 ์ดํ ๋ณํ๊ฐ ์๋ฏธํ๋ ๊ฒ
Lodash๊ฐ์ ํฌํผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์กด์ฑ ๊ฐ์- ์ฝ๋ ๋ฆฌ๋ทฐ ์ ์๋ ํ์ ์ด ์ฆ๊ฐ์
- TypeScript์์๋ ํ์ ์ถ๋ก ์ด ๋ ์ง๊ด์
ES2024๋ โ๊ฐ๋ฐ์์ ๋ฐ๋ณต ํจํด์ ์ธ์ด ๋ ๋ฒจ๋ก ์ฌ๋ ค์ฃผ๋โ ๋ฒ์ ์ด๋ผ๊ณ ๋ด๋ ์ข๋ค.
groupBy ์ธ์๋ ์ธ๊ธํ์ง ์์์ง๋ง, Array.prototype.with, toSorted ๊ฐ์ ๋ฌธ๋ฒ๋ค์ด ๊ทธ ๋ํ์ ์ธ ์๋ค.
๐ค Understanding
๊ฐ์ธ์ ์ผ๋ก๋ groupBy๊ฐ ๋จ์ํ ํฌํผ ๋ฉ์๋์์ ๋์ด โ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ผ๋ณด๋ ๊ด์ โ ์ ๋ฐ๊พธ๋ ๊ธฐ๋ฅ์ด๋ผ ์๊ฐํ๋ค.
- ๋ก์ง ๋จ์ํ: ๋ถํ์ํ
reduceํน์ ์ธ๋ถ ์์กด์ฑ ์ ๊ฑฐ - ๊ฐ๋ ์ฑ ํฅ์: ์ฝ๋ ์๋๊ฐ ๋ฐ๋ก ๋๋ฌ๋จ
- ํ์คํ๋ ์ ๊ทผ: ํ ์ปจ๋ฒค์ ํต์ผ ๊ฐ๋ฅ
์์ผ๋ก โ๋ฐ์ดํฐ ๊ทธ๋ฃนํโ์ด ํ์ํ ๋๋ถ๋ถ์ ์ํฉ์์ ๊ณ ๋ฏผ ์์ด ์ฌ์ฉํด๋ณผ ์๊ฐ์ด๋ค.