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

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

ただいまの
回答率

90.47%

  • JavaScript

    17012questions

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

Javascriptのループ文

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 379

SugiuraY

score 188

現在、Javascriptのループ文を学んでいるのですが、
以下の2点について、分からない部分があるため、どなたかご教示頂けますでしょうか。

1) do Whileについて

function printArray(a) {
var len = a.length, i=0;
if (len ==0)
 console.log ("Empty Array");
 else {
  do {
   console.log(a[i]);
   } while (++i< len); //この条件式がわからない
  }
} 


通常のfor文等であれば、条件式は (var i=0; i< len ; i++){処理}で記載され
initialize/test/incrementの過程が直感的に理解できます。
つまり、testを評価しtrueとなる限り、処理が実行されるということになろうかと思います。

一方で、学んでいる書籍について、上記のwhileの条件式は(++i< len)となっており、test自体がincrementしており、直感的に理解できません。

これはtestの中にincrementを含めることも認められる記法であるということなのでしょうか?
また、(i=0 ;4 < i < 9 ; i+=2)のような複雑な条件を組むことは可能なのでしょうか?

2) for文について

同じ書籍の例示に以下のような変わった例示があります。

function tail (o) {
for (; o.next; o=o.next) /*空文*/ //何がしたい?incrementもなくどうやってループしているの?
return o;


解説によれば、以下の2点に触れられています。
・ループ変数は数値であるとは限らない
・リンクリストoの末尾(nextプロパティを持たない最初のオブジェクト)を返す

上記oは具体的にどういうオブジェクトを想定しているのでしょうか?
下記のようなものと思ったのですがundefinedが返されるため、ご教示願えますでしょうか?
var obj = {
a: {next:"hit"},b:{next:"hit"}, c:{here:"not hit"};
}
また、オブジェクトの構造を巡回して検査をする構造であるとすれば、数値の場合にi++でループさせているのに対して、incrementもなくどのようにしてループさせているのか構造が理解できないのですが、併せてご教示頂けると幸いです。

長文となりまた至らぬ点も多く、申し訳ございませんが、
宜しくお願い申し上げます。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2017/10/03 11:27

    書籍については書籍名、版があればその数字、当該ページ番号を提示されたほうが良いと思います。

    キャンセル

回答 4

+6

 1) do Whileについて

これはtestの中にincrementを含めることも認められる記法であるということなのでしょうか?

はい。認められます。言ってみればforのtestのiにだってincrementしても動作します。incrementはあくまで「ここまで処理が来たらこの変数に1を足す」という記述なので、どこにだって書けます。

また、(i=0 ;4 < i < 9 ; i+=2)のような複雑な条件を組むことは可能なのでしょうか?

i+=2は大丈夫ですが、4 < i < 9は無理です。この場合2つの条件に分けて4 < i && i < 9と書きます。ちなみにこの処理だといきなりテストに失敗してforに入らないです。

 2) for文について

リンクリストというのは、「次のオブジェクトへの参照を持っているオブジェクトの一連の繋がり」です。

var a = {value:1};
var b = {value:5};
var c = {value:10};
a.next = b; // aのnextにbを入れる
b.next = c; // bのnextにcを入れる
c.next = null; // cで終わりにするためnextはnullとする

function tail (o) {
  for (; o.next; o=o.next); // aのnextはb、bのnextはc、cのnextはnullなのでそこで処理が止まる
  return o; // oにはcが入っている
}

var t = tail(a); // aから繋がりを探していき、nextがnullなオブジェクト、つまりcが返される

ちなみに上記の例において、c.nextaを入れると無限循環リストが出来上がります。永遠にnextを回り続けるリストなので、強制的に終了させるまでずっとループします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/03 13:36

    masaya_ohashisama様
    なるほど、リンクリストのことがよく分かりました。オブジェクトのなかに他のオブジェクトのプロティ(参照)を格納するという使い方をしたことがなかったのでいろいろな意味で勉強になりました。
    宜しくお願い申し上げます。

    キャンセル

checkベストアンサー

+4

1)

つまり、testを評価しtrueとなる限り、処理が実行されるということになろうかと思います。 

インクリメントに限らず、何をしようが、この考え方のままです。
この例なら++i<lenを評価してtrueならループします。
i=1,len=3なら2<3でtrueです。評価の過程でiには2が再代入されます。

例えばこれも動きます

let i=0;
let len=5;
do{
    console.log("do.")

}while(
    console.log("cond."+i),
    ++i<len
)

また、(i=0 ;4 < i < 9 ; i+=2)のような複雑な条件を組むことは可能なのでしょうか?

式なら何書いてもいいです。

ちなみに4 < i < 9(4 < i) < 9と解釈され、
(true または false) < 9となり、結局常にtrueなので、
意図したようには動きません。

2)

こういう構造です。
{value:1, next:{value:2, next:{value:3}}}

仮にこれが初期値だとすると

for (; o.next; o=o.next)

においてo

{value:1, next:{value:2, next:{value:3}}}
{value:2, next:{value:3}}
{value:3}


と遷移しますね。

incrementもなくどのようにしてループさせているのか

インクリメントはループ成立のための魔法の言葉ではありません。
ループが続くのは条件式がtrueと評価されるからで、
ループが終わるのは条件式がfalseと評価されるからです。

for文は、

for ([初期化式]; [条件式]; [更新式])
  文

という構造で、条件式が比較演算子を使っている必要もないし、
更新式がインクリメント演算子を使う必要もないです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/03 13:24

    ozwk様
    ご回答有難うございます。なんとなく制御文について構文のように覚えていたことについて、丁寧にご説明頂きとてもよく分かりました。
    一点だけ確認なのですが、もともと先入観でdo while (test)もfor(;;test)もtestについて、更新するための式(例えばi++)だけとおもっていましたが、
    while(
    console.log("cond."+i),
    ++i<len
    )や
    for (; o.next; o=o.next,console.log(o))/*空文*/;
    のように処理を記載しても構わのですね。。
    大変勉強になりました、心より感謝です。
    宜しくお願い申し上げます。

    キャンセル

+2

++iは前置インクリメントと呼ばれるもので、iの値を返す前にiに1を加えます。
なので、

i++;
i < len;


と同様の意味です。
 
o.nextについては、たぶん入出力的なオブジェクトなのかなあ、と。
oを無理やり再現するならこんな感じ。

var o1 = {
  next: null
}
var o2 = {
  next: o1,
  value: 'hoge'
}
var o3 = {
  next: o2,
  value: 'fuga'
}
var o = o3;
o.next; //o2

    

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/03 13:30

    ご回答有難うございます。
    確かに条件式について以下のとおりでも同じように動作しました。
    i++;
    i < len;
    これは
    i++<len
    でも同じようにtrueである限り変数iに+1ずつ加算されて評価しており、分けて記載する式と等価であるということなのですね、
    オブジェクトについては、書籍にはこれ以上の情報はないのですが、ozwk様が記載のとおり、再帰的な構造のデータなのかと印象を受けました。
    宜しくお願い申し上げます。

    キャンセル

+2

念の為・・・

for(i=0 ; 4< i < 9 ; i+=2){
は文法的には間違いではありませんが、おそらく質問者さんが期待する動作ではありません
test句について、式は左から順に評価されます

まずはi=0のとき、(4<0)が評価されfalse、それが(false<9)なのでtrueになります。
従ってiに2が足されループし、(4<2)=false,(false<9)=true
(4<4)=false,(false<9)=true,(4<6)=true,(true<9)=true,・・・・
となり結局ずっとtrueなので永久ループします

あらためて、iが4より大きく、9より小さいなら
4<i && i<9と書くべきです。
ただしi=0が、(4<i && i<9)を評価した時点で4<0=false && 0<9=true →false
なのでループしません。つまりやる意味はありません

いずれにしても、4<i<9的な書き方や評価をする意味がないということです

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/03 12:46

    yambejp様
    ご回答頂き誠に有難うございます。
    確かに永久ループしていまいました、どのようなロジックなのかと不思議に思っていたのですが、ご指摘の内容で納得を致しました。どうしても、特定の範囲で実行したいのであれば、初期値と条件式をうまく組み合わせて実行すればよいということなのでしょう。例:(i=4; i<9;i+=2)
    宜しくお願い申し上げます。

    キャンセル

関連した質問

同じタグがついた質問を見る

  • JavaScript

    17012questions

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