JavaScript에서 중첩(nested) 배열을 다루다 보면, 여러 깊이에 흩어져 있는 요소들을 하나의 문자열로 합쳐야 하는 경우가 종종 있습니다. 이번 글에서는 중첩 배열의 모든 요소를 재귀적으로 탐색하여 세미콜론(;)으로 연결된 하나의 문자열을 만드는 방법을 알아보겠습니다.
문제 상황
다음과 같은 중첩 배열이 있다고 가정해 보겠습니다.
const arr = ['zero', ['one', 'two', 'three', ['four', ['five', 'six', ['seven']]]]];
요구 사항은 중첩 배열을 인수로 받아, 배열 안의 모든 요소를 세미콜론(';')으로 연결한 문자열을 반환하는 JavaScript 함수를 작성하는 것입니다.
따라서 위 배열에 대한 기대 출력 결과는 다음과 같습니다.
const output = 'zero;one;two;three;four;five;six;seven';
해결 방법 1: 재귀 함수 사용
배열의 각 요소를 순회하면서, 해당 요소가 배열인지 Array.isArray()로 확인합니다. 배열이라면 그 안으로 들어가 같은 로직을 재귀적으로 수행하고, 배열이 아니라면 결과 문자열에 요소와 세미콜론을 붙여 나갑니다.
const arr = ['zero', ['one', 'two', 'three', ['four', ['five', 'six', ['seven']]]]];
const buildString = (arr = [], res = '') => {
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
// 중첩 배열이면 재귀 호출로 내부까지 처리
res = buildString(arr[i], res);
} else {
res += `${arr[i]};`;
}
}
return res;
};
// 마지막에 붙는 불필요한 세미콜론 제거
console.log(buildString(arr).replace(/;$/, ''));출력 결과
zero;one;two;three;four;five;six;seven
참고: 중첩 배열을 만났을 때 단순히 return으로 재귀 호출을 처리하면, 같은 레벨에 중첩 배열이 여러 개 있을 때 나머지 요소들이 누락될 수 있습니다. 위 코드처럼 재귀 호출의 결과를 res에 다시 할당하는 방식으로 작성하면 어떤 구조의 중첩 배열에서도 올바르게 동작합니다.
해결 방법 2: flat()과 join() 활용
ES2019부터 제공되는 Array.prototype.flat() 메서드에 Infinity를 인수로 전달하면, 아무리 깊은 중첩 배열이라도 한 번에 평탄화(flatten)할 수 있습니다. 이후 join()만 호출하면 훨씬 간결하게 같은 결과를 얻을 수 있습니다.
const arr = ['zero', ['one', 'two', 'three', ['four', ['five', 'six', ['seven']]]]];
const output = arr.flat(Infinity).join(';');
console.log(output);zero;one;two;three;four;five;six;seven
두 방법 비교
- 재귀 함수: 로직을 직접 제어할 수 있어 학습 목적이나 커스터마이징(구분자 변경, 특정 값 필터링 등)에 유리합니다.
- flat() + join(): 코드가 짧고 가독성이 좋으며, 별도의 구현 없이 표준 메서드만으로 해결됩니다.
상황에 맞는 방법을 선택해 중첩 배열을 손쉽게 하나의 문자열로 변환해 보시기 바랍니다.