質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

1446閲覧

JavaScript (ES5) 道場コース I「学習コース Ⅲ」の復習7. FizzBuzz問題に挑戦しよう での疑問点

wankoromochi

総合スコア2

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/09/17 07:54

編集2020/09/17 08:09

課題は以下の通りです。

繰り返し処理を用いて、「FizzBuzz」という有名な問題に挑戦してみましょう!

1から100までの数字を順番に表示してください。
ただし、
・その数が3で割り切れるなら
Fizz

・その数が5で割り切れるなら
Buzz

・3でも5でも割り切れるなら
FizzBuzz

をその数字の代わりに表示してください。

疑問1

なぜ、3の倍数「且つ」5の倍数の "&&" は、if文の中で先頭に書かないとダメなのでしょうか?

疑問2

以下のように記述すると、なぜ、3の倍数、5の倍数、3かつ5の倍数が、それぞれ、Fizz、Buzz、FizzBuzz にならず、数字の間に挟み込まれるのでしょうか?

JavaScript(ES5)

1for(var i = 1; i <= 100; i++ ){ 2 console.log(i); 3 if(i % 3 ===0 && i % 5===0){ 4 console.log("FizzBuzz"); 5 }else if (i % 5 ===0){ 6 console.log("Buzz"); 7 }else if (i % 3 ===0) { 8 console.log("Fizz"); 9 } 10}

イメージ説明

while分を使った場合でも

以下のように記述すると

JavaScript

1var i = 1; 2 3while(i <= 100) { 4 if(i%3===0 && i%5===0){ 5 console.log("FizzBuzz"); 6 }else if(i%3 ===0) { 7 console.log("Fizz"); 8 }else if(i%5 ===0){ 9 console.log("Buzz"); 10 } 11 console.log(i); 12 i ++; 13} 14 15コード

こうなります。↓
イメージ説明
なぜでしょうか?

初歩的な質問ですが、回答、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

なぜ、3の倍数「且つ」5の倍数の "&&" は、if文の中で先頭に書かないとダメなのでしょうか?

javascriptif .. else if .. elseは、条件に合致している場合は以降の条件で判定しないからです。
この例でいうと、「3の倍数「且つ」5の倍数」を先に書いておかないと**「3の倍数]もしくは「5の倍数」**の条件に引っかかってしまうからです。

例えば

javascript

1// 条件① 2if (i % 5 ===0){ 3 console.log("Buzz"); 4// 条件② 5}else if (i % 3 ===0) { 6 console.log("Fizz"); 7// 条件③ 8}else if(i % 3 ===0 && i % 5===0){ 9 console.log("FizzBuzz"); 10}

とした場合、条件②条件①が偽(false)の場合にはじめて評価されます。条件③も同様です。
したがって、この例だと15などの値も条件①に先に引っかかってしまうため、"Buzz"と表示されてしまいます。

以下のように記述すると、なぜ、3の倍数、5の倍数、3かつ5の倍数が、それぞれ、Fizz、Buzz、FizzBuzz にならず、数字の間に挟み込まれるのでしょうか?

console.log(i);iの値によらず、必ず実行されるためです。
もし数字の置き換えを実現したい場合はelseを追加してその中で実行するとよいです。

javascript

1for(var i = 1; i <= 100; i++ ){ 2 if(i % 3 ===0 && i % 5===0){ 3 console.log("FizzBuzz"); 4 }else if (i % 5 ===0){ 5 console.log("Buzz"); 6 }else if (i % 3 ===0) { 7 console.log("Fizz"); 8 } 9 // 上記のいずれも満たさない場合は数字を表示 10 else { 11 console.log(i); 12 } 13}

投稿2020/09/17 08:12

nekoniki

総合スコア2409

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wankoromochi

2020/09/19 05:29 編集

nekonikiさん、回答ありがとうございます。 『console.log(i);がiの値によらず、必ず実行されるためです。』は、理解しました。 ただ、FizzやBuzzが数字の間に挟み込まれるのは不思議です。
nekoniki

2020/09/19 05:42

> FizzやBuzzが数字の間に挟み込まれるのは不思議です。 例えば修正前のソースだとi=3の時に、 console.log("Fizz"); のあとに console.log(i); も実行されているためです。
guest

0

追記)
FizzBuzz 問題は、様々な処理を訓練するものであり、「1つの回答例だけが正解」というものではありません。
ただ、問題文から「ベン図を想像できる」だけの知識があることが望ましい題材です。

  1. 1から100 の数 という矩形のグループ ... 反復処理(for, while)のブロックで表現
  2. 3で割り切れる という円(Fizz)のグループ ... if 文などで切り分ける
  3. 5で割り切れる という円(Buzz)のグループ ... 同上
  4. 2.3. の重なったグループ ... 同上

ご質問(疑問2)で示されるコードは正しく切り分けができていませんので、if文を再確認する必要があります。

  • if(条件a) { 処理A } .. モシ、「条件aが真」ナラ、「処理A」ヲジッコウ
  • else if(条件b) { 処理B } .. ソウジャナク、「条件bが真」ナラ、「処理B」ヲジッコウ
  • else { 処理C } .. ソウジャナイナラ、「処理C」ヲジッコウ(条件aも条件bも共に偽のとき)

javascrit

1for(var i = 1; i <= 100; i++ ){ 2 //console.log(i); ... 割り切れるかどうかに関わらず、出力してしまっている 3 if(i % 3 ===0 && i % 5===0){ 4 console.log("FizzBuzz"); 5 } else if (i % 5 ===0){ 6 console.log("Buzz"); 7 } else if (i % 3 ===0) { 8 console.log("Fizz"); 9 } else { 10 console.log( i ) 11 } 12}

3の倍数「且つ」5の倍数の "&&" は、if文の中で先頭に書かないとダメなのでしょうか?

問題には要件として示されていませんので、「書かないと駄目」ということはありませんが、
ベン図を見ても分かるように、最も多くの条件を有した領域から消去法で if else を書く手法に過ぎません(重なっている部分を先に処理したほうが、あとで切り分けし直さなくて済むため)。

別段、以下のように、文字列の結合処理に着目した処理も正答です。

javascrit

1for(var i = 1; i <= 100; i++ ){ 2 var rslt = ""; 3 if (i % 3 ===0) rslt = "Fizz"; 4 if (i % 5 ===0) rslt += "Buzz" 5 if (rslt === "") rslt += i; // その数字の代わりに表示. 数値でなく数字と示されている 6 console.log( rslt ); 7}

※柔軟な考え方で様々な処理法がある問題ですので、「他人のコードを読む」、「他人にコードを読ませる」といった訓練に使われます。
(追記ここまで


A. 1

if文でelse を使っているからです。

A. 2

console.log(i) は割り切れるかどうかに関わらず、必ず出力しています。


有名な問題だけあって、検索するとヒットします

if を使わない例を書いてみました。

javascript

1for ( let i=1; i<=100; ++i ) { 2 let 3 Fizz = !(i % 3), 4 Buzz = !(i % 5), 5 Bit = (Fizz<<1) + Buzz, 6 out = !(Fizz + Buzz) ? i : (Fizz ? 'Fizz': '') + (Buzz ? 'Buzz': ''), 7 out2 = Object.entries({Fizz, Buzz}) 8 .reduce((a,[k,v])=>(v ? isFinite(a) ? k : a+k : a),i), 9 out3 = [i,"Fizz","Buzz","FizzBuzz"][Bit] 10 ; 11 console.log( out, out2, out3 ); 12}

主な確認事項:

投稿2020/09/17 09:27

編集2020/09/17 21:48
AkitoshiManabe

総合スコア5432

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wankoromochi

2020/09/19 05:33

回答、ありがとうございます。 『文字列の結合処理に着目した処理』は、難しくて理解できませんでした。 if (i % 3 ===0) rslt = "Fizz"; ifとrsltの間は、何も要らないのでしょうか? if (i % 5 ===0) rslt += "Buzz" +=が理解できません。
AkitoshiManabe

2020/09/19 06:30

if( 条件 ) { ステートメント1つ } のときには {} を省略できる特徴があります。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/if...else で、「statementが複数のときは{} を使ってください」と暗示されています(1つのときは省略できる) rslt+= "Buzz" は代入演算子で rslt = rslt + "Buzz" と同じです。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators#Assignment_operators
wankoromochi

2020/09/21 07:48

上段は知りませんでした。勉強になりました。 下段の rslt = rslt + "Buzz" は判ります。これにより rslt が "FizzBuzz"というカタチで文字列の連結になるという解釈で合っていますか?
AkitoshiManabe

2020/09/21 07:55

その 2つめの if 文までに rslt は 3で割り切れなかった "" または 3で割り切れた "Fizz" になっていますので、5で割り切れた場合は "Buzz" または "FizzBuzz" に文字列結合されます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問