JavaScript에서는 첫 번째 인수로 1차원 배열을, 두 번째 인수로 숫자 n을 받아 부모 배열 내부에 n개의 하위 배열을 생성하고(가능한 경우), 요소들을 적절히 분배하는 함수가 필요할 때가 있습니다.
분배 조건과 제약 사항
여기서 중요한 제약 조건이 있습니다. 예를 들어 배열에 9개의 요소가 있고 4개의 하위 배열을 만들어야 한다고 가정해 보겠습니다. 각 하위 배열에 2개씩 나누면 총 5개의 하위 배열이 필요하고, 3개씩 나누면 3개의 하위 배열로 충분합니다. 이런 경우에는 정확히 n개가 아니라 가장 가까운 낮은 개수(이 경우 3개)로 대체(fallback)해야 합니다. 요구 사항은 마지막 하위 배열만 일부 특수한 경우를 제외하고 각 하위 배열에 가능한 한 동일한 수의 요소를 분배하는 것이기 때문입니다.
예시
// 입력 배열이 다음과 같고, const arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']; // 분할할 개수가 2라면, // 출력 결과는 아래와 같아야 합니다. const output = [ [ 'A', 'B', 'C', 'D', 'E' ], [ 'F', 'G', 'H', 'I' ] ];
이제 해당 기능을 구현한 코드를 살펴보겠습니다.
구현 코드
const arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'];
const splitArray = (arr, rows) => {
const itemsPerRow = Math.ceil(arr.length / rows);
return arr.reduce((acc, val, ind) => {
const currentRow = Math.floor(ind / itemsPerRow);
if(!acc[currentRow]){
acc[currentRow] = [val];
}else{
acc[currentRow].push(val);
};
return acc;
}, []);
};
console.log(splitArray(arr, 2));코드 동작 원리
이 코드의 핵심 로직은 다음과 같습니다.
1. 행당 요소 수 계산: Math.ceil(arr.length / rows)를 사용해 각 하위 배열이 담을 수 있는 최대 요소 수를 구합니다. 위 예시에서는 Math.ceil(9 / 2) = 5가 됩니다.
2. 현재 인덱스의 행 계산: Math.floor(ind / itemsPerRow)로 각 요소가 몇 번째 하위 배열에 속하는지 판단합니다.
3. reduce로 배열 구성: reduce 메서드를 활용해 빈 배열에서 시작하여, 각 요소를 자신이 속한 행에 순차적으로 추가합니다. 해당 행이 아직 없으면 새로 생성합니다.
출력 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[ [ 'A', 'B', 'C', 'D', 'E' ], [ 'F', 'G', 'H', 'I' ] ]
이처럼 Math.ceil과 reduce를 조합하면 별도의 반복문 없이도 간결하게 1차원 배열을 원하는 개수의 2차원 배열로 분할할 수 있습니다. 페이지네이션 데이터 처리나 테이블 레이아웃 구성 등 다양한 상황에서 유용하게 활용할 수 있습니다.