문제 상황
다음과 같이 숫자로 이루어진 중첩 배열(nested array)이 있다고 가정해 보겠습니다.
const arr = [23, 6, [2, [6, 2, 1, 2], 2], 5, 2];
이 배열의 모든 요소(숫자)를 화면에 출력하는 프로그램을 작성해야 합니다. 핵심 조건은 숫자가 중첩된 깊이(level)에 따라 들여쓰기가 적용된 형태로 출력되어야 한다는 점입니다.
따라서 위 입력값에 대한 출력 결과는 다음과 같아야 합니다.
23
6
2
6
2
1
2
2
5
2
해결 아이디어
배열을 재귀적으로 순회하면서 각 요소가 배열인지 확인하고, 배열이라면 한 단계 더 깊은 들여쓰기를 적용해 내부 요소를 출력하는 방식으로 해결할 수 있습니다. 이때 Array.isArray() 메서드와 reduce() 함수를 함께 활용합니다.
예제 코드
전체 코드는 다음과 같습니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>PATTERN</title>
</head>
<body>
<script>
const arr = [23, 6, [2, [6, 2, 1, 2], 2], 5, 2];
arr.reduce(function iter(level) {
return function (node, item) {
var pTag = document.createElement('p');
pTag.style.marginLeft = level + 'px';
node.appendChild(pTag);
if (Array.isArray(item)) {
item.reduce(iter(level || 50), pTag);
} else {
pTag.appendChild(document.createTextNode(item));
}
return node;
};
}(0), document.body);
</script>
<p></p>
</body>
</html>
코드 설명
- iter 함수: 들여쓰기 수준(level)을 매개변수로 받아 실제 순회에 사용할 함수를 반환하는 고차 함수입니다.
- p 태그 생성: 각 숫자마다 <p> 요소를 만들고, CSS의 marginLeft 속성으로 중첩 깊이만큼 들여쓰기를 적용합니다.
- 재귀 호출: 요소가 배열인지
Array.isArray()로 판별한 뒤, 배열이라면 level을 50px씩 증가시키며 iter를 재귀 호출해 하위 요소를 처리합니다. - 텍스트 노드 추가: 일반 숫자라면
createTextNode()로 텍스트를 만들어 p 태그에 추가합니다.
이 코드를 브라우저에서 실행하면, 위에서 확인한 것처럼 중첩 깊이에 따라 계단식으로 들여쓰기된 숫자들이 화면에 순서대로 출력됩니다.