중첩된 배열(nested array)이 주어졌을 때, 모든 요소를 한 겹의 배열로 펼쳐내는 작업을 배열 평탄화(flattening)라고 합니다. 이번 글에서는 JavaScript를 사용해 깊이 중첩된 리터럴 배열을 재귀(recursion) 방식으로 평탄화하는 함수를 직접 구현해 보겠습니다.
문제 정의
하나의 중첩 배열을 인수로 받아, 입력 배열에 포함된 모든 리터럴(literal) 요소를 중첩 없이 담고 있는 새로운 배열을 반환하는 JavaScript 함수를 작성해야 합니다.
예시
입력 배열이 다음과 같다면 —
const arr = [
1, 3, [5, 6, [7, [6, 5], 4], 3], [4]
];출력 배열은 아래와 같아야 합니다.
const output = [1, 3, 5, 6, 7, 6, 5, 4, 3, 4];
재귀 함수로 구현하기
가장 대표적인 접근 방식은 재귀 호출입니다. 배열의 각 요소를 순회하면서 해당 요소가 배열인지 확인하고(Array.isArray()), 배열이라면 자기 자신을 다시 호출해 내부 요소를 펼친 뒤 결과에 이어 붙입니다.
const arr = [
1, 3, [5, 6, [7, [6, 5], 4], 3], [4]
];
const flattenArray = (arr = []) => {
const res = [];
for(let i = 0; i < arr.length; i++){
const el = arr[i];
if(Array.isArray(el)){
// 요소가 배열이면 재귀적으로 평탄화
res.push(...flattenArray(el));
}else{
// 일반 값이면 그대로 추가
res.push(el);
};
};
return res;
};
console.log(flattenArray(arr));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[
1, 3, 5, 6, 7,
6, 5, 4, 3, 4
]더 간단한 방법: Array.prototype.flat()
ES2019(ES10)부터는 flat() 메서드를 사용해 훨씬 간결하게 처리할 수 있습니다. 인수로 Infinity를 전달하면 어떤 깊이로 중첩된 배열이든 한 번에 평탄화됩니다.
const output = arr.flat(Infinity); console.log(output); // [1, 3, 5, 6, 7, 6, 5, 4, 3, 4]
정리
재귀 방식은 평탄화 과정의 동작 원리를 명확히 이해할 수 있다는 장점이 있고, flat(Infinity)는 코드가 짧고 가독성이 좋다는 장점이 있습니다. 상황과 지원해야 하는 환경에 따라 적절한 방법을 선택하면 됩니다.