プログラミング入門 再帰的な処理とは?

数値と回数の二つの引数を受け取って、数値を回数分配列にpushする処理を考えてみます。


const createArray = (value, times) => {
	let result = []
  for (let i = 0; i<times; i++){
  	result.push(value)
  }
  return result
}

const result = createArray(3, 2)
console.log(result) //[3, 3]

それではこれを再帰的に書き換えてみます。

const createArray = (value, times) => {
	if(times <= 0) return []
  return [value, ...createArray(value, times - 1)]
}

createArray の中では自分自身を呼び出しています。これが再帰的な処理です。

しかし、それだけでは無限に自分自身を呼び出してしまいます。

そこで、if(times <= 0) return [] により、再帰処理を止める条件を書きます。

この部分を基底部といいます。再帰処理を考える場合、まずは基底部を考えるとやりやすいと思います。

今回の場合は、回数が0回なら結果として変えす配列も空になるので、この条件を基底部として書きます。

再帰処理だと何が違うのか

関数型プログラミングでは再帰処理はよくでてきます。Haskellではそもそも繰り返しの構文がないので、再帰処理をマスターすることが必須になります。

それでは、for文を使った書き方と再帰的な書き方では何が違うのでしょうか。

for文を使った書き方では、どういった処理をするかをコードに書きます。

一方で、再帰的な書き方の場合は、その処理の定義を書きます。

つまり、再帰的な createArray の場合は、0なら空配列を返し、それ以外はvalueとcreateArray(value, times – 1)を結合した配列を返す処理、と定義されます。

このように表現することを宣言的と言うこともあります。

再起的な考え方はマスターするとプログラムを書く時の表現力は上がると思います。

ただし、再帰処理の場合は慣れていない人からするとかなりストレスなので、参画するプロジェクトの様子をみながら検討した方が無難だと思います。