[Javascript]おばあとおじいの1週間の献立を無理やり再帰にする準備をする
背景
「どうせ学んでいるのならアウトプットせい!」とお叱り愛の叱咤激励をもらいました。
ごもっともなので毎日投稿を習慣化してみる。
自己紹介(=情報の信頼度)
2020年4月から学習をはじめた駆け出しエンジニア
HTML、CSS、Javascript、React、Vue、Laravelを学習
AWSもamplifyとかS3、EC2あたりをちょこっと。ふくおか。
今日のおはなし
〜おじいおばあの家〜
おばあ「今週のごはんは何にしようか。」
おじい「精のつくものとらねばねえ。」
おじい「しかし、ついつい昨日のごはんも忘れてしまうとよ。困ったもんちゃ!」
おばあ「では、私が「1週間の献立」をつくってみようかね」
おばあ「最近、ぷろぐらみんぐ教室で学んだの。」
お題
[朝、昼、夜]の献立表をつくる。
献立表=[
[🍛、🍛、🍛][🍛、🍛、🍣][🍛、🍛、🍜]
[🍛、🍣、🍛][🍛、🍣、🍣][🍛、🍣、🍜]
[🍛、🍜、🍛][🍛、🍜、🍣][🍛、🍜、🍜]
[🍣、🍛、🍛][🍣、🍛、🍣][🍣、🍛、🍜]
[🍣、🍣、🍛][🍣、🍣、🍣][🍣、🍣、🍜]
[🍣、🍜、🍛][🍣、🍜、🍣][🍣、🍜、🍜]
[🍜、🍛、🍛][🍜、🍛、🍣][🍜、🍛、🍜]
[🍜、🍣、🍛][🍜、🍣、🍣][🍜、🍣、🍜]
[🍜、🍜、🍛][🍜、🍜、🍣][🍜、🍜、🍜]
]
※おじいさんとおばあさんは、カレー、寿司、ラーメンしかたべません。
再帰を学ぼう!
再帰とは
関数が自分自身を呼ぶこと。
たとえば、繰り返し処理(forループ)を、
こう書き換えられる。
この場合、
n==3であれば、x*pow(2,3) //-> 2*2
n==2であれば、x*pow(2,3) //-> 2*2*2
n==1になるとき、x*pow(2,3)//-> 8
となっている。
@fujitanozomu様にご指摘いただきました!ありがとうございます!
0乗が正しく求まらないので書き換えられていないのでは
仰られる通りです。ご指摘いただきありがとうございます。
下記に訂正いたします。
function pow(x, n) {
if (n == 0) {
return 1;
} else {
return x * pow(x, n - 1);
}
}
再帰を考えるときのコツ
再帰を終了する条件:ベースケース
再帰を継続する条件:リカーシブケース
と呼ぶらしい。
再帰関数自体にベースケース、リカーシブケースに関係する値を引数としていれておくこと。
実際に再帰で考えてみよう!
おばあ「まず、全体の流れを理解しよう。」
おばあ「すべての献立パターンがつくれて、関数を実行すると「献立表」が返ってくる。」
おばあ「食べ物は、食糧庫からとってこよう。」
おばあ「朝、昼、夜、の3食決まったら再帰は終了だね。間食はしないからね」
おばあ「じゃあ、まだ朝、昼までしか決まっていないときは、再帰を継続する必要があるね。」
おばあ「これでよしっと。」
おばあ「繰り返し処理になっている部分は、、と。」
おばあ「各食事に対してpantryからすべての食事を取り出す。」
おばあ「まず、[🍛、🍛、🍛]をつくるには、」
おばあ「1回目の食事を[🍛]いれて、2回目の食事にする。」
おばあ「2回目の食事を[🍛]いれて、3回目の食事にする。」
おばあ「3回目の食事を[🍛]いれて、3食分の献立をresultにいれる。」
おばあ「このあたりが繰り返しの処理っぽいな。」
おばあ「次に、[[🍛、🍛、🍣]をつくる。]
おばあ「途中まで[🍛、🍛]をつくってるから、その上に対して🍣を入れたいけど、どうしようか」
おばあ「作成途中の献立[🍛、🍛]を受けとれるようにしよう。」
おばあ「作成途中の献立を受け取れるように引数を変更して、」
おばあ「それらに対してpantryから次の食事を加えよう。」
おばあ「これで、自分自身を呼ぶことで、配列を作るrecuse関数ができあがった」
おばあ「あ。recuse関数の発火をしてない。えい。」
const menu = (numberOfMeals=3) => {
// Your code here
const pantry = ["🍛", "🍣", "🍜"];
let result = [];
function recurse(meal=[],numberOfMeals) {
if (numberOfMeals > 0) {
//再帰の処理
for (let i = 0; i < pantry.length; i++) {
recurse(meal.concat(pantry[i]),numberOfMeals - 1,)
}
} else {
//3食分の献立ができたので終了する
result.push(meal)
}
return result;
}
return recurse([],numberOfMeals)
};
その後
おばあ「meal()[1]」
おじい「もぐもぐ」
おばあ「meal()[4]」
おじい「もぐもぐ」
補足
pushではなく、concatで記述している理由は、配列のままにしたいからです。
pushだと要素数を返す
=>数字になる。
=>昼のごはんが選べなくなる
=cannnot read proptyとなるため避けています。
recuse関数外にresultを定義しているのはクロージャーを使いたいためです。
後日記事にします。
解釈間違い等、何かあればぜひコメントください。
誰か再帰の使いみちを教えてください・・・。
Author And Source
この問題について([Javascript]おばあとおじいの1週間の献立を無理やり再帰にする準備をする), 我々は、より多くの情報をここで見つけました https://qiita.com/nktuk/items/13fb11ef63125f84c64b著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .