では「再帰版」と「ループ版」を並べて比較してみましょう。両方で同じ処理を実装すると、どこが似ていてどこが違うのかが見えてきます。
例:階乗(factorial)
ループ版
function factorialLoop(n) {
let result = 1;
for (let i = n; i > 0; i--) {
result *= i;
}
return result;
}
console.log(factorialLoop(5)); // 120
JavaScript再帰版
function factorialRec(n) {
if (n === 0) return 1; // 終了条件
return n * factorialRec(n - 1);
}
console.log(factorialRec(5)); // 120
JavaScript👉 違い
- ループは「変数を回して積み上げる」。
- 再帰は「問題を小さく分けて、戻りながら積み上げる」。
例:配列の合計
ループ版
function sumLoop(arr) {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
console.log(sumLoop([2, 4, 6])); // 12
JavaScript再帰版
function sumRec(arr, i = 0) {
if (i === arr.length) return 0; // 終了条件
return arr[i] + sumRec(arr, i + 1);
}
console.log(sumRec([2, 4, 6])); // 12
JavaScript👉 違い
- ループは「インデックスを進めて合計」。
- 再帰は「先頭 + 残りの合計」という分割の考え方。
例:ネストした配列の合計
ループ版(難しい)
// ネストの深さが決まっていれば書けるが、
// 深さが不明だとループだけでは複雑になる。
JavaScript再帰版(シンプル)
function sumNested(arr) {
let sum = 0;
for (const item of arr) {
if (Array.isArray(item)) {
sum += sumNested(item); // 再帰で深く潜る
} else {
sum += item;
}
}
return sum;
}
console.log(sumNested([1, [2, [3, 4]], 5])); // 15
JavaScript👉 違い
- ループは「深さが決まっているとき」に強い。
- 再帰は「深さが分からない入れ子構造」に強い。
まとめ
| 方法 | 得意な場面 |
|---|---|
| ループ | 繰り返し回数がはっきりしている処理(for, while) |
| 再帰 | 入れ子構造や木構造、問題を分割して解く処理 |
ここまでで「ループと再帰は同じこともできるけど、得意分野が違う」というのが見えてきたと思います。
