문제 소개
정수로 이루어진 배열을 인자로 받아, 배열의 모든 요소를 곱한 값을 반환하는 자바스크립트 함수를 작성해 보겠습니다. 이때 지켜야 할 핵심 조건은 두 가지입니다.
반복문이 아닌 재귀(recursion) 방식으로 문제를 해결할 것
배열 내 모든 요소의 곱(product)을 계산하여 반환할 것
입력 및 출력 예시
입력 배열이 다음과 같다고 가정해 보겠습니다.
const arr = [1, 3, 6, .2, 2, 5];
모든 요소를 곱하면 1 × 3 × 6 × 0.2 × 2 × 5 = 36이므로, 기대되는 출력값은 다음과 같습니다.
const output = 36;
재귀를 이용한 해결 코드
매번 배열의 첫 번째 요소를 하나씩 제거하면서 곱을 누적하는 방식으로 구현할 수 있습니다.
const arr = [1, 3, 6, .2, 2, 5];
const arrayProduct = ([front, ...end]) => {
// 기저 조건: 배열이 비어 있으면 곱셈의 항등원인 1을 반환
if (front === undefined) {
return 1;
}
return front * arrayProduct(end);
};
console.log(arrayProduct(arr)); // 36
코드 동작 원리
이 코드의 핵심은 구조 분해 할당(destructuring)과 나머지 연산자(rest operator)입니다. 매개변수 [front, ...end]는 전달받은 배열을 자동으로 첫 번째 요소(front)와 나머지 요소들(end)로 분리해 줍니다.
기저 조건(Base Case): 배열이 비어 더 이상 꺼낼 요소가 없으면
front는undefined가 되고, 이때 곱셈의 항등원인 1을 반환해 재귀를 종료합니다.재귀 단계(Recursive Step): 첫 번째 요소
front에 나머지 배열에 대한 재귀 호출의 결과를 곱해 반환합니다.
호출 과정을 단계별로 표현하면 다음과 같습니다.
arrayProduct([1, 3, 6, .2, 2, 5]) → 1 * arrayProduct([3, 6, .2, 2, 5]) → 1 * 3 * arrayProduct([6, .2, 2, 5]) → 1 * 3 * 6 * arrayProduct([.2, 2, 5]) → 1 * 3 * 6 * .2 * arrayProduct([2, 5]) → 1 * 3 * 6 * .2 * 2 * arrayProduct([5]) → 1 * 3 * 6 * .2 * 2 * 5 * arrayProduct([]) → 1 * 3 * 6 * .2 * 2 * 5 * 1 = 36
출력 결과
콘솔에는 아래와 같이 최종 곱이 출력됩니다.
36
마무리
재귀와 구조 분해 할당을 조합하면 반복문 없이도 간결하게 배열의 곱을 구할 수 있습니다. 다만 배열의 길이가 매우 길 경우 콜 스택 오버플로(stack overflow)가 발생할 수 있으므로, 실무에서는 reduce() 메서드를 활용한 방식도 함께 고려하는 것이 좋습니다.