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

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

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

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

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

Q&A

解決済

11回答

13031閲覧

for文はもう使わない?

退会済みユーザー

退会済みユーザー

総合スコア0

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

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

3グッド

5クリップ

投稿2017/09/20 09:25

編集2017/09/21 09:08

for文はもう使わない?

forおじさんと揶揄されていますがJS、phpなどではすでに使わないほうがいいのでしょうか?
極力whileを使って、どうしても使わざるおえないときのみ使うべきなのでしょうか?

ただwhileでできない事はまったくないと聞くので一切使わない手もありますね。

読みにくいからでしょう?

皆さんありがとうございます。
沢山ご回答いただいたのでここで一括にお返事させてもらいます。

まだfor文を使うのは有りなのですね。
単純な繰り返し、繰り返しの回数が決まっていない場合は、
最速はwhileをとりあえず使い。

何回繰り返すか、決まっている場合でwhileでは無理のある場合のみforで良い。
という感じですかね。

yuba, yohhoy👍を押しています

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

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

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

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

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

t_obara

2017/09/20 09:46

なぜforを使わない方が良いと言われているのかお調べになりましたか?その理由を調べ、その理由に納得できれば結論が出るかと思います。もちろんwhileを代わりにという結論にはならないと思います。
alg

2017/09/20 10:25

使わざる負えない → 使わざるを得ない
guest

回答11

0

forを使わないとは、どんな文脈で言われたことかにもよりますが、おそらく「whileを使え」という意味ではありません。
「集合演算を使え」ということではないかと。
map, filter, reduce などといったキーワードで探していただくといろいろ出てくると思うのですが、ループを回して要素一個一個に対する処理を書くのでなく、「各要素についてこの処理を適用せよ」的に、列そのものを操作対象にしていく記法です。

投稿2017/09/20 09:49

yuba

総合スコア5568

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

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

0

「JS、phpなど」とありますので、JavaScriptとPHP以外についてそれぞれ取り上げてみました。

###Go

Goにはwhileがありません。無限ループや単純な条件ループはwhileの代わりにforを使う必要があります。

###Ruby

Rubyのforは使う理由がありません。ブロックを作らないというただ一つの違いを除きeach呼び出しと同じだからです。私は(検証などを除いて)Rubyでforを書いたことは一度もありません。

###Java

拡張for文がまだまだ使えると思います。StreamのforEachというのもありますが、ラムダ式に制限が多い(finalまたは暗黙finalなローカル変数しか使えないとか、検査例外を非検査例外にする必要があるだとか)ので使いやすいとは言えないです。

###C++

範囲ベースfor文が非常に使えます。for_eachってあまり使った覚えが無いです。こちらもラムダ式を扱うのが面倒だからかもしれません。

###C

そもそもfor_each等の代替となる関数や仕組みが標準で用意されていません。配列の要素を辿る場合は、0からnまでの数値を増やしながらの順次処理にするしかないのですが、whileで代用すると非常に読みにくくなってしまいます。ただ、null終端文字列などは最後が\0であることを利用して、whileを使った方が良い場合があります(strcpyの実装例等)。

###Python

forを禁止にされると便利な内包表記まで使えなくなってしまいます。forを使わないというのはあり得ないです。

###Haskell

Haskellにはforがありません。

投稿2017/09/20 11:05

raccy

総合スコア21735

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

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

0

PHPでやるなら9割の状況でforeach。
なぜならばPHPがHTMLの動的生成がゴールになることが多い以上、配列を触る状況が殆どだから。

whileやfor文は何度動作するのかを常に把握し続ける必要がある、
1回多くループが回っても、1回少なくループが回っても駄目。
状態変数が増えてソースコードが読みづらくなった結果、不具合が発生しやすくなる。
(特に九九の掛け算や多次元配列を操ると一気にネストが深くなり状態変数も一気に増える)

配列操作に限定されるけどforeachを使えば何度ループが回るかが一目。
配列のアイテムが既に取り出せた状態から始まるから状態変数の管理も不要といい事ずくめ。
またforやwhileと比較してもほぼ等速なのでforeach以外を使う意味がない。

残り僅かのケースは速度がどうしても遅いからチューニングする事になって、
無からわざわざrange(1, 10)みたいな事をしてforeachを使うのは賛否両論があるから、for ($i = 0; $i < 10; $i++)はわざわざ避ける必要はない。
fopen、feofみたいな低級関数(低俗という意味ではなく、マシン語に近いという意味ね)を使う場合はwhileがよく使われる。

まぁ、PHPは多くの配列操作用のビルトイン関数が揃っているから、
筋の良い関数を使ってワンライナーで書ける場合はforeachすら不要。
下記の関数が一例(他にもあるかも)

yambejpさんの一例は賛否あるだろうけど個人的には好き。
PHPならではの良さを考えると富豪的で分かりやすい手法はあって良いと思う。


JavaScriptもDOM操作の元になる配列を作ったり、Ajax通信でPHPからJSONを貰ってきて解析する事が多い。
やはり配列の操作がメインになるから純粋な配列やオブジェクトを用意して、for (;;)やwhileを避けて開発するべきだね。
(こねくり回した不順な配列やオブジェクトはthink49さんが言うようにfor...in等でprototypeが紛れ込む罠がある)

JavaScriptでやる場合for...offor...inを使っていくとPHPのforeachと同じ事が出来る。
ただ、for...ofは古いブラウザに非対応だし、for...inはkeyが来るのでPHPのforeach程汎用的に使えるわけじゃない。
yubaさんの言うようにリスト操作用のメソッドを利用していくのがベースになる。

高速なライブラリや関数を作るならforやwhileを使いまくりになると思うけどね。
もちろんその分のテストもすべきだし、ライブラリの中身は可読性ガン無視で良いわけでもないから考えて使うのは重要だと思う。


追記部分への対応

何回繰り返すか、決まっている場合でwhileでは無理のある場合のみforで良い。

という感じですかね。

for文の速度に関しての言及は特に無かったけど、別にwhileだから速いということは無い。
言語にもよるけど、コンパイラが解釈して同じマシン語に変換されるので同じ速度になる可能性もある。

もっと言うと、for文で1箇所にまとめた方が良いマシン語に変換されて速く動作する可能性すらある。
本当に速度を気にするならちゃんとコンパイラの実装まで確認した方がいい。
(私は確認したこと無いけど、100万回程ループ回して比較しているベンチマーク記事とか結構あるからね)

なんとなくwhileの方がやってること少ないから速そうだからと、何でもかんでもwhileで書くのはやめて、まずは可読性の事を考えよう。

投稿2017/09/20 09:48

編集2017/09/23 00:34
miyabi-sun

総合スコア21158

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

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

0

for 文

JavaScriptにおいては、古い環境(PC)でも安定して高速に動作するので、今でも for は使います。
ただ、実際のところ、3つめのエリアは使わなくても書けるので while で書くことが多いですが。

JavaScript

1for (var i = 0, len = array.length; i < len; ++i) { // ++i のエリアが要らない 2 array[i] = 1; 3} 4 5// ↓ 6 7for (var i = 0, len = array.length; i < len; ) { // 3つめのエリアが空欄で無駄 8 array[i++] = 1; 9} 10 11// ↓ 12 13var var i = 0, len = array.length; 14while (i < len) { // while で十分 15 array[i++] = 1; 16}

ただし、for 文で配列を走査する場合、値の存在しない要素も undefined と評価してしまう問題があります。

JavaScript

1var array = [,,2]; 2 3for (let value of array) { 4 console.log(value); // undefined -> undefined -> 2 5} 6 7for (var i = 0, len = array.length; i < len; ++i) { 8 console.log(array[i]); // undefined -> undefined -> 2 9} 10 11array.forEach(v => console.log(v)); // 2 12 13for (var i = 0, len = array.length; i < len; ++i) { 14 if (array.hasOwnProperty(i)) { 15 console.log(array[i]); // 2 16 } 17}

逆にいえば、Array#forEach はプロパティの存在確認という手順を for 文よりも多くしている為、パフォーマンス効率が悪いと判断する事も出来ます。
値の存在しない配列に遭遇する機会がどれだけあるかは分かりませんが、この性質は留意しておく必要があります。

for 文以外の構文、関数

一般に for 文が非推奨とされるのは、同一スコープ上に存在する変数の数が多くなり、保守性が低下するからです。
constlet を使えば解決する問題ですが、スコープを分ける場合には他にも選択肢があります。

  • Array.prototype.forEach, Array.prototype.filter 等の Array.prototype 系メソッド (ES5)
  • for-of (ES6)
  • Map.prototype.forEach (ES6)
  • Object.keys() (ES5)
  • Object.values(), Object.entries() (ES8)

しかしながら、Array.prototype.filter は配列全体を検索して新しい配列を生成して返す関数であり、目的を見据えて実装しないとパフォーマンスが低下する懸念があります。
その処理は破壊的で良いのか、非破壊的でなければならないのか、は良く考えて実装する必要があります。

私は for 文は、まだ現役だと思っていますよ。
使用頻度は低下しているかもしれませんが、選択肢の一つとして持っておくのは悪くないと思います。

Re: amebatv さん

投稿2017/09/20 11:58

編集2017/09/20 12:07
think49

総合スコア18162

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

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

0

ベストアンサー

ループ回数が最初から分かっている場合なら、for を使う。
ループ回数が不定なら while, do-while を使う。
リスト構造などに対する全体処理なら foreach なり集合関数を使う。

結局のところ適材適所であって、for だからというだけで否定するのは賢いとは言えませんね。
リストからデータを削除していくような場合だと、foreach 系は使えず(foreach の最中に、元の集合を追加・削除するのは禁忌事項です)、for を逆順で回して処理する、なんて使い方もしますが。
※別の集合に入れていく手もありますが、メモリを食うしガベージコレクションが汚くなるしで、やりたかないですねえ

投稿2017/09/20 10:15

tacsheaven

総合スコア13703

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

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

退会済みユーザー

退会済みユーザー

2017/09/22 06:30

forよりもwhileが優れているからforを使うのはやめよう。という主張ではないのですね。 ループ回数が最初から分かっている場合なら、for を使う。 ループ回数が不定なら while, do-while を使う。 リスト構造などに対する全体処理なら foreach なり集合関数を使う。 という順番で考えて選べばよいというのが結論のようですね。 皆さんありがとうございました。
miyabi-sun

2017/09/22 06:50

> リストからデータを削除していくような場合だと、foreach 系は使えず ダサくて筋が悪いのは確かですが、PHPのforeachは元の配列に破壊的な変更が加わろうとするとコピーを取って整合性を保とうとする挙動なんで不具合が出るわけではありませんね。 ```PHP <?php $items = [1, 2, 3, 4, 5]; foreach ($items as $key => $item) { if ($item === 3 || $item === 4) { unset($items[$key]); } } var_dump($items); array(3) { [0]=> int(1) [1]=> int(2) [4]=> int(5) } ``` ちゃんと4も削除されますね。 因みにforeachの中で`$items[] = 123`みたいな事やっても無限ループにはなりません。 まぁ、コピー後の本物と切り離された物体Xを元に本物を捜査し始めて沼になるって意味ならその通りですが…
think49

2017/09/22 14:39

> ループ回数が最初から分かっている場合なら、for を使う。 配列などのリスト構造を前提にしていると思うのですが、for文のループ条件は array.length に限定されないので、そういう使い分けと思い込んでしまうと視野が狭まってしまうように思いました。 厳密には、「初期化式」もしくは「各反復の終了時に呼び出す式」が必要ならforを使う、ではないかと。
guest

0

比較的初心者ですけど、回答してみます。

処理内容によるのではないでしょうか?

例えばリストや配列などを回すときにforwhileを使うのは確かに良くないと思います。無駄な繰り返し変数が必要だからです。
forEachmap等を使うのが今は一般的でしょう。

しかしリストや配列を使わずに処理を繰り返したいならばそれこそforを使う方が読みやすいでしょうし、特定条件(終了するイベントなどでしょうか?)を元に処理を続けるかを判断するのにはwhileが適していると思います。

またforの代用がwhileに務まるかと言われるとそうではない気がします。

「どんな処理にも」forを使うのは古いと思いますが、中にはforが適した処理もあります。それが言いたかったことです。

投稿2017/09/20 09:48

namnium1125

総合スコア2043

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

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

miyabi-sun

2017/09/20 10:00

この意見は同意ですが、JSに限った状況ですね。 PHPはarray_mapやarray_walkの使い勝手がゴミ(useであれこれ持ち込んだり、外で宣言して適用するという事がやりづらい)なんで、一時期使いまくってましたが、筋が悪いという結論が出ました。 Qiitaなんかでもtadsan氏の「array_mapにありがとうさようなら」のような使うな記事も出てますしね。 関数型プログラミング的ではなく、オブジェクト指向的でちょっと宣言的な書き方にして気をつけるのが現実的だと思います。
namnium1125

2017/09/20 10:07

コメントありがとうございます。 完全にjavascriptサイドの発言でした。すみませんm(_ _)m Python派でしてPHPは全然なんですよね…言語問わずfor文一般に言えるかなと思い回答しました。 ところで、回答しておきながらこの場で聞くのもアレですが、 for文が嫌われる理由があるとすると、for(;;)の;;に色々と複雑な処理を「書けてしまう」からというのも理由の一つなんでしょうか?可読性の低下をもたらすので嫌われたんじゃないかなと、、
rkojima

2017/09/20 11:00 編集

forを使うために一時変数を用意する必要がある(大体 $iとかでわかりにくい名前)というのもあると思います。 「すべての要素に対して処理したい」とだけなのに、$i や $len の意味まで把握しないといけない。というのはストレスかなと。 ループがネストしたら顕著ですね。 ※よく読まずに見当違いのコメントしてました。すみません。
namnium1125

2017/09/20 11:47

いえいえ、コメントありがとうございます。 繰り返し変数といい複雑な処理が書けてしまうことといい、結局可読性の問題なんでしょうね。多分。
think49

2017/09/20 13:36

> forを使うために一時変数を用意する必要がある(大体 $iとかでわかりにくい名前)というのもあると思います。 その理由が大半だと私も思いますが、個人的にはあの泥臭い手間が嫌いではないです。 変数をやりくりして効率の良い処理が書けた時の達成感とか、原始的な for, while 文だからこそ出来る事もあります。 例えば、最近書いたコードは最速を自負できる程のベンチマーク結果を残せましたが、一般的には受け入れられないだろうなあとも思います。 https://gist.github.com/think49/2a30b4e865f3dca4043440fb9b99a448 ただ、for や while は余計な処理がない単純処理だからこそ、アルゴリズムを工夫してパフォーマンスを向上させやすい面は確かにあると思います。
miyabi-sun

2017/09/21 02:39

forやwhileが読みづらくバグが混入し易いのはPHPも同様ですが、 PHPはmapやforEachに相当するarray_mapやarray_walk関数がイケてないという事情ですね。 for(;;)自体は悪くないと思いますよ。 黒魔術書いちゃう子は三項演算子のネストとかし始めるんでどの道駄目です。 特に以下の2つの使い方に限定すればバグもほぼ混入しないでしょうし、命令も簡素、whileと比べて1行で済み可読性も高いです。 - `for(i = 0; i < 10; i++)`: 0〜9の10回ループ - `for(i = 1; i <= 10; i++)`: 1〜10の10回ループ このように初期値を0か1に限定する所がポイントですね。 困ったことに世の中にはiの初期値が0や1じゃない可能性があり、そういう時はかなり辛いです。 特にループが何度回るのかは机上デバッグや関数の外からでは判別しにくいですからね…
namnium1125

2017/09/21 04:25

三項演算子のネストって恐怖ですねΣ(°□°) 勉強になりました。ありがとうございます。
guest

0

forよりもwhileが優れているからforを使うのはやめよう。という主張ではないと思います。

ほかの方が答えられている通りfor/whileで書くよりもわかりやすい記述ができる(場合が多い)ので、一番わかりやすい形でコーディングしよう。という心がけ?的なものではないでしょうか。

投稿2017/09/20 10:32

rkojima

総合スコア421

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

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

0

前提は配列操作なのでしょうか?
であれば、miyabi-sun さんの回答がしっくりきます。

ただ、なんでもかんでも同じループ使うのか?というのは、疑問があり。
回答している方、それぞれできたら聞きたいのが・・・

無限ループ(そもそも、やらないという回答もあり)
n回リトライ(わざわざ、n要素数の配列を作る?)

とか、記載してくれると勉強になります。

投稿2017/09/20 10:14

momon-ga

総合スコア4820

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

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

miyabi-sun

2017/09/20 12:58

> 無限ループ これは`while(true)` 遭遇したエンジニアが「おっ、無限ループだ気をつけよう」って一目で分かる所がポイント高い。 > n回リトライ(わざわざ、n要素数の配列を作る?) 関数で閉じ込めておきたいから、基本再帰でやってるよ。
退会済みユーザー

退会済みユーザー

2017/09/20 13:53

> 関数で閉じ込めておきたいから、基本再帰でやってるよ。 目からウロコでした。ワリと定石なんですかね。 勉強になりました。
guest

0

forもwhileも副作用があるので使わないで良いです。再帰処理で対応出来ますし。
もちろん、それらを使っても良いですが。(phpの場合は分かりません。)

投稿2017/09/20 09:35

編集2017/09/21 00:45
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2017/09/20 09:48

マイナス2評価喰らった!
guest

0

感覚的にPHPでforを使う機会がほぼないですね
ループ処理はほぼwhileかforeachしか使わないし
繰り返し文字列の制御も配列系の関数でやることが多いです

prepare処理のために「?」を指定回数連結する

PHP

1print implode(",",array_fill(0,10,"?"));

連続する数字をつなげる

PHP

1print implode("-",range(10,20));

投稿2017/09/20 11:20

yambejp

総合スコア114784

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

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

0

せっかくなのでまだ挙がっていないC#について言います。

2005年の、C# 3.0 からあるLINQが使いやすくなっていて、確実にfor/foreachを使う機会は減ったといえます。一プロジェクト中に一回も出てこないこともあり得ます。
ループ中の分岐も不要になる場合が多く、for/foreachよりもわかりやすいので使わない手はないと思います。

投稿2017/09/21 00:56

x_x

総合スコア13749

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問