なぜFizzBuzzの条件文を一番上にもっていかなければならないのか?

このQ&Aのポイント
  • FizzBuzzの条件文を一番上にもっていかないと、意図した動作が行われない可能性があります。
  • continue;はその位置での処理を終了し、次の繰り返しに進むため、その上の条件文が実行されなくなってしまいます。
  • したがって、FizzBuzzの条件文は一番上にもっていく必要があります。
回答を見る
  • ベストアンサー

JSについて教えてください。

// FizzBuzz let i = 0; while(i < 100) { i++; if(i % 3 === 0){ console.log('Fizz'); continue; } if(i % 5 === 0){ console.log('Buzz'); continue; } if(i % 5 === 0 && i % 3 === 0){ console.log('FizzBuzz'); continue; } console.log(i); document.getElementsByClassName('js-test210')[0].innerHTML = i; } ・ 上記のように作成したのですが、 if(i % 5 === 0 && i % 3 === 0){ console.log('FizzBuzz'); continue; } の部分を一番上にもっていかないとこちらがうまくいかない理由がわかりますか? ・ continue; はこれ以下の処理は実行しないようにするという意味のようですが、 if内の記載以下の処理を実行しないようにするということなのでしょうか? ただそれだともともとそれ以下に何もないですよね???

noname#226032
noname#226032

質問者が選んだベストアンサー

  • ベストアンサー
  • bya00417
  • ベストアンサー率35% (56/158)
回答No.1

continue はループ内の処理を中断し次のループへ進める命令です。 例示されているプログラムだと while(i < 100) { ・・・・ } の「・・・・」の部分が一回のループ処理です。 最初に「if(i % 3 === 0)」が評価され該当すると「console.log('Fizz');」を実行して continue になるので、それ以降のループ内の処理は実行されず次のループとしてループ処理の先頭に戻ってしまいます。 「if(i % 5 === 0 && i % 3 === 0)」が「if(i % 3 === 0)」より後にあると、「if(i % 3 === 0)」の処理が先に実行されるため「if(i % 5 === 0 && i % 3 === 0)」に辿り着く前に処理が中断されるので、永遠に「console.log('FizzBuzz');」が実行される事はありません。 「if(i % 5 === 0 && i % 3 === 0)」を最初に判定すると2つの条件が友に成立した時だけif文内の処理が実行され、両方が成立しない時だけ次の判定に進み、一つずつ条件が成立する場合の処理が行われます。 プログラムは原則として上から順に実行されるので、条件判定の順番は優先されるもの、複数条件が指定されるものから順に書いていかないと、目的の処理に到達する前に他の条件に合致して処理されてしまいます。

noname#226032
質問者

お礼

>>> 最初に「if(i % 3 === 0)」が評価され該当すると「console.log('Fizz');」を実行して continue になるので、 それ以降のループ内の処理は実行されず次のループとしてループ処理の先頭に戻ってしまいます。 真だった時のみcontinueが実行されるので真だった場合のみ100回繰り返さずに、 console.log('Fizz');だけ実行して他は一切実行せずに終了するということですね。 そして偽だったら何も行わずに次の5%のifに移りくりかえることにより、 真だった物だけ実行され偽だったものは実行されない状態を再現したのですね。 i++;はcontinueがないので必ず100回くりかえるということですね。 >>> 「if(i % 5 === 0 && i % 3 === 0)」を最初に判定すると2つの条件が友に成立した時だけif文内の処理が実行され、両方が成立しない時だけ次の判定に進み、一つずつ条件が成立する場合の処理が行われます。 プログラムは原則として上から順に実行されるので、条件判定の順番は優先されるもの、複数条件が指定されるものから順に書いていかないと、目的の処理に到達する前に他の条件に合致して処理されてしまいます。 if(i % 3 === 0){ console.log('Fizz'); continue; } if(i % 5 === 0){ console.log('Buzz'); continue; } if(i % 5 === 0 && i % 3 === 0){ console.log('FizzBuzz'); continue; } 上記の順番だと始めの二つのどちらかないしは両方が成立してしまうと、その時点で処理が終わってしまうので、 最後の処理がされることは100%ない矛盾した順番になってしまうのですね。 最後の複数条件は必ずifの先頭にないといけないかtうi++より上になってはいけないということですね。 確かにこちらは両方が真の時に実行するので片方ないしは両方が真であれば最後まで処理される前に終了しますね。

その他の回答 (2)

回答No.3

>continue; はこれ以下の処理は実行しないようにするという意味のようですが、 >if内の記載以下の処理を実行しないようにするということなのでしょうか? 「for文、do…while文、while文」などのループの先頭に戻ると言う意味です。 >if(i % 5 === 0 && i % 3 === 0){ >console.log('FizzBuzz'); >continue; >} >の部分を一番上にもっていかないとこちらがうまくいかない理由がわかりますか? 「i % 5 === 0 && i % 3 === 0」が真になる場合を考えてみて下さい、「5でも割り切れ、かつ 3でも割り切れる」場合の例を1つ挙げると「i=15」ですので、「i=15」で説明すれば分かりやすいでしょう。 >if(i % 5 === 0 && i % 3 === 0){ >console.log('FizzBuzz'); >continue; >} ↑これが一番下で「i=15」場合 >if(i % 3 === 0){ >console.log('Fizz'); >continue; >} で真になって >console.log('Fizz'); >continue; ↑そのif文のブロックが実行され、「continue」でループの先頭に戻ってしまうので、それ以降の文は無視されてしまいます。 >if(i % 5 === 0 && i % 3 === 0){ >console.log('FizzBuzz'); >continue; >} ↑これが一番上で「i=15」場合 >console.log('FizzBuzz'); >continue; ↑そのif文のブロックが実行され、「continue」でループの先頭に戻ってしまうので、それ以降の文は無視されます。

  • b0a0a
  • ベストアンサー率49% (156/313)
回答No.2

continueはforやwhileループ内で使い、今回のループの以後の処理を打ち切って、次回のループへ入るためのキーワードです こういったことは基本中の基本です MDNのこのページを隅から隅まで読めば分かるようになります https://developer.mozilla.org/ja/docs/Web/JavaScript

関連するQ&A

  • 【C】fizzbuzzのトリッキーなコードについて

    C言語でのfizzbuzz問題の回答を探していたら、以下のようなコードがありました。 #include <stdio.h> int main(void){ int i; for(i = 1 ; i <= 100 ; i++){ printf("%d \0Fizz \0FizzBuzz "+(i%5?(i%3?0:4):(i%3?14:10)),i); } printf("\n"); return 0; } (引用元:http://revilog.com/2010/08/c-fizzbuzz-printf.html) このコードについての質問です。 printf("%d \0Fizz \0FizzBuzz "+(i%5?(i%3?0:4):(i%3?14:10)),i); で、以下のことは理解しました。 ・\0で区切って文字列の終わりを作っておく ・+演算子でポインタ演算を行なっている ・三項演算子でポインタ演算する量を決めている ・+演算子によって指定したポインタから\0までの文字列を出力する ・Buzzを出力する際は、「FizzBuzz」の途中の「Buzz」を出力している わかっていないところは、 ・特殊文字(\0など)や「%d」は何バイトとして計算するのか ・数字以外を出力する際、%dによって桁数がずれ、変なところから出力されてしまうのではないか(でも実際はならない) です。 以上2点について回答よろしくお願いします。

  • JavaScriptの問題に関して教えてください。

    下記問題の解き方および答えが考えても全然分からず、お教えいただきたいです。お願いいたします。 以下のプログラムを読んで、どういったプログラムなのかを説明してください。 let change = 0; let change_sum = 0; const data = [ 31, 41, 59, 26, 53, 58, 97, 93, 23, 84 ]; console.log("並べ替える前"); for (let i = 0; i < data.length; i++) { console.log(data[i] + " "); }// for console.log("\n"); console.log("***********************************"); console.log(""); for (let i = 0; i < data.length - 1; i++) { for (let j = i + 1; j < data.length; j++) { if (data[i] > data[j]) { let a = data[i]; data[i] = data[j]; data[j] = a; change++; }// if }// for(内側1) console.log((i + 1) + "回目"); console.log(`${change}回`); for (let k = 0; k < data.length; k++) { process.stdout.write(data[k] + " "); }// for(内側2) console.log("\n"); change_sum += change; change = 0; }// for(外側) //最終結果の表示 console.log("***********************************"); console.log(""); console.log(`${change_sum}回`); console.log("最終結果"); for (let i = 0; i < data.length; i++) { process.stdout.write(data[i] + " "); }// for console.log("");

  • [JS]setTimeoutでクラス関数を使いたい

    他の処理を待ってから、別の処理を実施したい場合に、setTimeoutを使用するのが 一般的だと思いますが、特定のクラスの関数を実行する方法がよくわかりません。 グローバル変数を使用する場合には以下で動きます。 ※待機の部分は、問題を簡略化するため今回は3回実行完了まで、としています。 counter = 0; max = 3; method(); function method(){ if ( counter < max ) { timerId = setTimeout(method, 10 ); console.log(counter); counter++; } else { console.log("done"); } } 出力は以下のとおり。 0 1 2 done methodやcounter, maxなどを隠蔽するため、クラス関数を作り、以下のようにしました。 a = new test(); a.method(); function test(){ this.counter = 0; this.max = 3; this.method = function(){ if ( this.counter < this.max ) { timerId = setTimeout(this.method, 10 ); console.log(this.counter); this.counter++; } else { console.log("done"); } } } 出力は以下のようになってしまい、意図したように実行できていません。 0 done このような場合、どのようにしてクラス関数を再呼び出しするのでしょうか。

  • Node.js ファイル操作の非同期処理について。

    現在Node.jsを勉強しているのですが。 下記が教材に書いてあった、ソースコードです。 -------------------ここから------------------ const fs = require('fs'); // ファイルの書き込み fs.writeFile('test.txt', 'テストファイルの中身です。', function(err) { if (err) { console.log('エラー発生。'); console.log(err); return; } // ファイル読み込み。エンコーディングを指定する必要がある fs.readFile('test.txt', {encoding: 'utf8'}, function(err, data) { if (err) { console.log('エラー発生。'); console.log(err); return; } console.log('読み込んだ内容:' + data); }); }); // ここですぐにファイルを読むのは誤り! // この時点ではファイル書き込みがされている保証はない -------------------ここまで------------------ なのですが、このコメント部分の説明 // ここですぐにファイルを読むのは誤り! // この時点ではファイル書き込みがされている保証はない これは合ってますか? この場合、タスクキューに、 「ファイルの書き込み操作」がエンキューされ。 「ファイルの読み込み操作」がエンキューされ。 コールスタックが空になったら、 「ファイルの書き込み操作」がデキューされ実行。 コールスタックが空になったら、 「ファイルの読み込み操作」がデキューされ実行。 という処理を踏むと思うのですが。違うのでしょうか。 コメントの部分に、console.log("終了")って書いてしまうと、一番最初に終了って文字が出てしまうと思うのですが。 ファイル操作に関しては、タスクキューに入るので、順番に実行されるような気がします。 よろしくお願いします。

  • Fizz-Buzz問題のソース

    プログラミングの初心者です。 Fizz-Buzz問題をPHPで書いてみました。 <?php for ($i=1; $i<=100; $i++) { if ($i%3==0 && $i%5==0) { // 3でも5でも割り切れる数 echo "Fizz-Buzz"; } elseif ($i%3==0 && $i%5!==0) { // 3で割り切れる数 echo "Fizz<br>"; } elseif ($i%3!==0 && $i%5==0) { //5で割り切れる数 echo "Buzz<br>"; } else{ //3でも5でも割り切れない数 echo "$i<br>"; } } ?> こんな感じになったのですが、何か問題点はあるでしょうか? ちなみに、echo末尾に<br>を入れているのは、<br>なしで作ると、12Fizz4Buzz……と改行なしに表示されて読みにくかったからです。 インターネット上のソースを見ると、$i%3==0 && $i%5==0 ではなく $i%15==0 にしていたり、三項演算子を使ってバイト数を減らしたりと色々工夫がされているようですが、そちらのほうがよいのでしょうか。

    • 締切済み
    • PHP
  • ショートカット演算(短絡演算)について

    ショートカット演算(短絡演算) 以下の❶❷は意味的に等価です。 ◉リスト2-31 logical2.js if (x === 1) { console.log('こんにちは'); } ← ❶ x ===1 && console.log('こんにちは'); ← ❷ 上記は おそらく左がx=1ではないという仮定なので、左側がfalseになりこの時点で右側は実行されないので下記の二つは同じということだと思いますか?

  • 1から始まってクリックするたびに1増えるようにした

    下記の式をイベントリスナーに入れて1から始まってクリックするたびに1増えるようにしたいのですが二度目からNaNになります。 let i ; let stage = ++i; console.log(stage); 再宣言のiが何度も実行されるのがまずいのでしょうか?

  • node.jsのシェル上で

    コンソール上でnodejsを起動してシェルとしてつかった場合 var x="グローバル変数"; console.log(x); //とするとグローバル変数と出力されます。 さらに console.log(this.x); //とするとグローバル変数と出力されます。 そもそもグローバル変数とはトップレベルコードにおけるオブジェクトのプロパティとあります。 ブラウザだと、トップレベルのスコープで定義した変数は alert(window . variable); でアクセスできます。 ですから、nodeコンソール上で xとっ宣言した変数がthis.xとトップオブジェクトとしてアクセスできることはわかったのですが これをコンソールではなく、jsファイルに描いてそれをnodeコマンドで実行した場合 ~$ node test.js といった具合に実行させた場合 どうも、undefindeと表示されてしまうのです。 これは何が原因でundefinedと出力されてしまうのでしょうか?

  • js初心者 consoleなどについて

    初心者で恐縮ですが、よろしくお願いします。 jqueryを使用してます。 $(function () { obj = function(attr){ $.get('getFileList.php', {attribute : attr.data.value }, function(data){var array = data;}); }; delete obj; $("#file").on('input', {value:'file'}, obj); }); #fileに入力があったらobjが発動し$.getでphpから値を得て出力するという処理を書いています。 うまくいかないので変数arrayにちゃんと値が入っているか確認しようとしconsole.log(array)としたところjsのソースコードがconsoleにそのまま表示され、console.logを消してみてもまったく変化がなくなってしまいました。(console.log(array)したことが原因なのかは不明です。これを描いたあたりから変化がなくなっていたような気がするので。) やってみたこととしてはキャッシュの削除と.onの呼び出しの前にオブジェクトを削除することです。 ですが、やはりその変更点もconsoleに反映されてません。  初歩的かもしれませんがよろしくお願いします。

    • ベストアンサー
    • AJAX
  • moment.js

    moment.js moment.jsで秒の部分(17:00:「00」)を削るにはどうしたら良いでしょうか? 以下ソースです。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>サンプル</title> </head> <body> <script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.2/moment.min.js"></script> <script type="text/javascript" src="jquery-1.7.2.min.js"></script> <script type="text/javascript" src="moment.js"></script> <script src="fastclick.js"></script> <script> var now = moment(); console.log(now.toDate()); // Dateオブジェクトが返される // 文字列からも生成できるし var shougatsu = moment('2015-01-01'); console.log(shougatsu.toString()); // "Thu Jan 01 2015 00:00:00 GMT+0900" // もちろんDateオブジェクトからも生成できる var kodomonohi = moment(new Date('2015-05-05')); console.log(kodomonohi.toString()); // "Tue May 05 2015 09:00:00 GMT+0900" </script> </body> </html> コンソールログで表示をしているのですが何時何分何秒の「秒」の部分を非表示にしたい場合どうしたら良いでしょうか?