初心者にとって再帰関数はわかりにくいものです。
入門書などの「再帰関数」を見ると、フィボナッチ数などが例に挙がっていますが、そもそも「フィボナッチ数って何?」と、謎が深まるばかり。
そこで、もう少し判りやすいところで再帰関数を使ってみます。ここでは、「数字1234567を、文字列1,234,567にする」という処理を行います。
どんな処理を行うのか文章にしてみる
- 与えられた数字から下位3桁(1000で割った余り)を切り出す。 1234567 → "567"
- まだ上の桁があるので、先ほど切り出した文字列の頭にカンマ(,)をつける。 "567" → ",567"
- 3桁より上の桁(1000で割った値)から、再び下位3桁を切り出す。 1234 → "234"
- まだ上の桁があるので、切り出した文字列の頭にカンマ(,)をつける。 "234" → ",234"
- 2.で作った文字列とつなげる ",234,567"
- 6桁より上の桁(さらに1000で割った値)があるので、再び3桁を切り出す。 1 → "1"
- もう上の桁がないので、5.で作った文字とつなげて終了 "1,234,567"
この流れを見ると、元の数字が何桁になっても、
1. 下3桁切り出す
2. カンマをつける
3. すでに作った文字列とつなげる
を繰り返すことで、所望する文字列が得られそうです。
プログラムにしてみる
func commaNumber(number: Int, low: String = "") -> String {
if number < 1000 {
return String(number) + low // (1)
}
let last3Keta = number % 1000 // (2)
let last3KetaString = ("000" + String(last3Keta)).suffix(3) // (3)
let newlow = "," + last3KetaString + low // (4)
return commaNumber(number: number / 1000, low: newlow) // (5)
}
commaNumber(number: 1234567) // 1,234,567
(1) numberが1000未満であれば、numberを文字列にして、下位文字列とつなげた文字列を返す(再帰処理の終了)。
(2) numberを1000で割ることで、下位3桁を切り出す。
(3) 下位3桁を文字列にする。このとき、numberが100未満だと3桁にならないので、頭に"000"を付け、下位3桁分だけ取り出している。
(4) 先頭にカンマをつけ、末尾に下位文字列をつなげる。
(5) numberを1000で割った値と(4)で作った文字列を、commaNumberに渡す(再帰処理)。
という処理になります。
この処理は単純な繰り返しなのでforループでも実現可能ですが、再帰処理の入門には良いのではないでしょうか。
なおこの処理は、公開アプリなどでは使わない方が良いです(多言語化をサポートしたライブラリを使うべき)。