🛠️ 처음부터 만드는 Chunk — 배열을 일정 크기로 나누기
# 배열을 일정 크기로 나누는 것이 필요한 이유
상황 1: API가 "최대 100개씩만 요청 가능"이라고 할 때, 1000개 배열을 자동으로 100개씩 묶어야 합니다.
상황 2: 그리드 UI에서 3열씩 표시해야 할 때, 9개 아이템을 3개씩 3행으로 나눕니다.
상황 3: 데이터 처리에서 메모리 제약이 있을 때, 큰 배열을 작은 청크로 나눠서 처리합니다.
바로 `chunk()` 함수가 필요한 순간입니다.
```typescript
function chunk(arr: T[], size: number): T[][] {
const result: T[][] = [];
for (let i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}
return result;
}
// 사용 예
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(chunk(numbers, 3));
// [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
```
간단하지만, 엣지 케이스를 처리해야 합니다.
```typescript
function chunk(arr: T[], size: number): T[][] {
// 입력 검증
if (!Array.isArray(arr)) throw new TypeError('첫 번째 인자는 배열이어야 합니다');
if (size <= 0) throw new Error('크기는 0보다 커야 합니다');
// 빈 배열이면 빈 배열 반환
if (arr.length === 0) return [];
const result: T[][] = [];
for (let i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}
return result;
}
// 테스트
console.log(chunk([1, 2, 3], 2)); // [[1, 2], [3]]
console.log(chunk([], 3)); // []
console.log(chunk([1], 5)); // [[1]]
```
```typescript
function chunkRecursive(arr: T[], size: number): T[][] {
if (arr.length === 0) return [];
return [arr.slice(0, size), ...chunkRecursive(arr.slice(size), size)];
}
```
더 함수형이지만, 큰 배열에서 스택 오버플로우 위험이 있습니다.
```typescript
// API 배치 요청
async function batchFetch(ids: string[], batchSize: number = 100) {
const batches = chunk(ids, batchSize);
for (const batch of batches) {
const results = await fetch('/api/items', {
method: 'POST',
body: JSON.stringify({ ids: batch })
}).then(r => r.json());
console.log(`배치 처리 완료: ${batch.length}개`);
}
}
// 그리드 렌더링
const items = [...]; // 1000개 아이템
const rows = chunk(items, 3); // 3열씩
rows.forEach(row => renderGridRow(row));
```
더 알아보기: [Lodash chunk](https://lodash.com/docs#chunk), [Array.prototype.slice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
상황 1: API가 "최대 100개씩만 요청 가능"이라고 할 때, 1000개 배열을 자동으로 100개씩 묶어야 합니다.
상황 2: 그리드 UI에서 3열씩 표시해야 할 때, 9개 아이템을 3개씩 3행으로 나눕니다.
상황 3: 데이터 처리에서 메모리 제약이 있을 때, 큰 배열을 작은 청크로 나눠서 처리합니다.
바로 `chunk()` 함수가 필요한 순간입니다.
기본 구현
```typescript
function chunk
const result: T[][] = [];
for (let i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}
return result;
}
// 사용 예
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(chunk(numbers, 3));
// [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
```
간단하지만, 엣지 케이스를 처리해야 합니다.
견고한 버전
```typescript
function chunk
// 입력 검증
if (!Array.isArray(arr)) throw new TypeError('첫 번째 인자는 배열이어야 합니다');
if (size <= 0) throw new Error('크기는 0보다 커야 합니다');
// 빈 배열이면 빈 배열 반환
if (arr.length === 0) return [];
const result: T[][] = [];
for (let i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}
return result;
}
// 테스트
console.log(chunk([1, 2, 3], 2)); // [[1, 2], [3]]
console.log(chunk([], 3)); // []
console.log(chunk([1], 5)); // [[1]]
```
재귀 버전 (함수형)
```typescript
function chunkRecursive
if (arr.length === 0) return [];
return [arr.slice(0, size), ...chunkRecursive(arr.slice(size), size)];
}
```
더 함수형이지만, 큰 배열에서 스택 오버플로우 위험이 있습니다.
실무 예제
```typescript
// API 배치 요청
async function batchFetch(ids: string[], batchSize: number = 100) {
const batches = chunk(ids, batchSize);
for (const batch of batches) {
const results = await fetch('/api/items', {
method: 'POST',
body: JSON.stringify({ ids: batch })
}).then(r => r.json());
console.log(`배치 처리 완료: ${batch.length}개`);
}
}
// 그리드 렌더링
const items = [...]; // 1000개 아이템
const rows = chunk(items, 3); // 3열씩
rows.forEach(row => renderGridRow(row));
```
더 알아보기: [Lodash chunk](https://lodash.com/docs#chunk), [Array.prototype.slice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
👁 0 views
Comments (0)
💬
No comments yet.
Be the first to comment!