forループ内で、可能であればブレーク条件を条件フィールドに移動する必要がありますか?[閉まっている]


48

時々、次のようなブレークが必要なループが必要です:

for(int i=0;i<array.length;i++){
    //some other code
    if(condition){
        break;
    }
}

書くことに不快感を覚える

if(condition){
    break;
}

3行のコードを消費するためです。そして、ループは次のように書き換えられることがわかりました。

                                   ↓
for(int i=0;i<array.length && !condition;i++){
    //some other code
}

だから私の質問は、可能であればコードの行を減らすために条件を条件フィールドに移動するのは良い習慣ですか?


7
condition特に何に依存します。
ベルギ

4
misraがループ内で「break」および「continue」の使用を禁止する理由があります。:また、この参照stackoverflow.com/q/3922599/476681
BЈовић

35
行数自体は本当の問題ではないと思います。1行で記述できます。if(condition)break; 私の意見では、問題は読みやすさです。私は、ループ条件を使用する以外に、ループを壊すことを個人的に嫌います。
ジョー

97
なぜなら、3行のコードを消費するから です。スタイルを嫌う非常に、非常に悪い理由です。IMOの「コードの消費」は、無関係なものと良いものの間のどこかにあります。あまり多くのロジックを少なすぎる行に詰め込もうとすると、コードが読めなくなり、見つけにくいバグが発生します。
アンドリューヘンレ

3
おそらく不人気な意見:for(int i=0;i<array.length && !condition;i++)比較的一般的ではなく、コードをざっと読んでいるだけでは見落とされる可能性があります。これは、ループ定義に複数のブレーク条件がある場合が多いwhileor do whileループの適切な使用例です。
ジュール

回答:


154

これらの2つの例は機能的に同等ではありません。オリジナルでは、条件テストは「その他のコード」セクションの後に実行されますが、修正版では、ループ本体の開始時に最初に実行されます。

行数を減らすことを唯一の目的として、コードを書き換えないでください。明らかにそれはそのようにうまくいくとき素晴らしいボーナスですが、それは読みやすさや正確さを犠牲にして行われるべきではありません。


5
私はあなたの感情を理解していますが、ループが数百行の長さであり、複数の条件付きブレークがあるレガシーコードを十分に維持しています。コードが期待する条件付きブレークに到達すると予想する場合、デバッグが非常に難しくなりますが、以前のコードは最初に条件付きブレークを実行しました。そのコードをどのように処理しますか?上記のような短い例では、この種の非常に一般的なシナリオを簡単に忘れてしまいます。
ベリンロリッチュ

84
@BerinLoritsch:それに対処する正しい方法は、長さ数百行のループを持たないことです!
クリス

27
@Walfrat:書き直しがオプションではない場合、それ以上の質問はありません。通常、「メソッドの抽出」タイプのリファクタリングを使用すると、コードのブロックを移動してメインメソッドのループを短くし、ロジックフローをより明確にすることができます。それは本当にケースバイケースです。私は短い方法を保つための私の一般的なルールに立つと、間違いなくnextedループロジック短いを保つが、私は一般的な意味でより多くのそれよりも何も言わしようとしたくないでしょうけれども...
クリス・

4
@AndrewHenleの簡潔さは、少なくとも冗長性を高めると常に可読性と保守性低下するという意味で、可読性です。LOCの削減は、密度を高め、抽象化レベルを上げることで達成され、このサイトの他のQ / Aペアで証明されているように、保守性と非常に密接に相関しています。
ルーシェンコ

5
Do-Whileの@Joeコンストラクトは非常にまれなので、後でそのコードを維持する必要がある開発者をつまずかせる傾向があります。少数の開発者が実際にそれらを見たことはありません!どちらかといえば、それはでしょう-ん、しばらくは、すべての可読性を改善するかどうかはわからないんだけど増やすコードを理解する難しさを。ちょうど例として-私の現在のコードベースは約15歳であり、約200万LOCを持っています。約50人の開発者が既にそれに触れました。do-whileループはまったくありません!
T.サー-モニカーの復活

51

私は「3行のコードを消費する」という議論を買いません。結局のところ、次のように書くことができます。

if (condition) break;

1行を消費するだけです。

ifループの途中で表示される場合は、当然、別のテストとして存在する必要があります。ただし、このテストがブロックの最後に表示される場合は、ループの両端に継続テストを持つループを作成しているため、コードの複雑さが増している可能性があります。ただし、if (condition)テストはブロックが実行されて初めて意味をなす場合があることに注意してください。

しかし、そうではないと仮定して、他のアプローチを採用することで:

for(int i=0;i<array.length && !condition;i++){
    //some other code
}

終了条件は一緒に保持されるため、物事を単純化できます(特に「他のコード」が長い場合)。

もちろん、ここには正しい答えはありません。そのため、言語のイディオム、チームのコーディング規約などに注意してください。しかし、バランスをとるには、機能的に意味がある場合は単一のテストアプローチを採用します。


14
@ jpmc26、ベター?いいえ。有効な代替スタイルですか?もちろん。
デビッドアルノ

6
後でコードを編集するときに混乱するのが難しく、顕著な欠点はありません。
jpmc26

4
「ループの内容が長くなる可能性がある」ためにそれらをまとめることは、弱い議論のようです。forコンテンツが読みにくい場合、2行のコードを保存する以外の問題があります。
BlueWizard

12
@ jpmc26同意しない。この回答のように、ブレースは最短の1ライナー条件では不要です。なしでは、よりエレガントで目に優しいです。それらは三項条件演算子のようなものです。ブレースを追加して、より大きなステートメントブロックに分割することを忘れていません。結局、すでに改行を追加しています。
benxyzzy

3
それはすべてスタイル設定ですが、それがより安全であると主張するなら、私はその理由に反対します。私自身は中括弧なしで次の行を好むが、それが他のスタイルよりも有効であるという意味ではない
-phflack

49

この種の質問は、プログラミングが行われている限りほぼ議論を巻き起こしました。私の帽子を指輪に放り込むために、私はbreak条件のあるバージョンに行きます、そして、この理由はここにあります(この特定のケースのために):

forループは、ループ内で反復値を指定するだけの存在です。その中で破壊条件をコーディングすると、ロジックIMOが混乱します。

別個のものbreakがあると、通常の処理中に値がforループで指定されたとおりになり、条件が発生した場合を除いて処理を続行する必要があることが明確になります。

ちょっとした背景として、私はaのコーディングを始めbreak、その後for何年も(例外的なプログラマーの指示の下で)条件をループに入れ、それからbreakスタイルに戻りました。私が消費していたさまざまなコードの本)。

それは、一日の終わりに、これらの聖なる戦争のもう一つです-いくつかは、あなたがすべきであると言う決して人為的にループから抜け出すない、そうでなければ、本当のループではありません。読みやすいと思うものは何でも(自分と他の人の両方のために)してください。キーストロークを減らすことが本当に重要な場合は、週末にコードゴルフをお楽しみください。ビールはオプションです。


3
条件に「found」などの適切な名前がある場合(たとえば、配列を調べて何かを探している場合)、forループの先頭に配置することをお勧めします。
user949300

1
for繰り返しの回数がわかっているとき(たとえば、配列/リストの終わり以外に破損条件がないとき)と知られていないとき、ループが使用されると言われましたwhile。これはwhileループの場合のようです。読みやすさが懸念事項である場合idx+=1、ループ内の読み取りはif/elseブロックよりもはるかにクリーンです
Laiv

それに続くコードがある場合、ループにブレーク条件を置くことはできないため、少なくとも「if(条件){found = true; continue;}
gnasher729

私たちはfor(int i=0; i<something;i++)ループに慣れているので、開発者の半分は、forループの使い方が違うことを覚えていないので、その&&condition部分を理解するのに苦労しています。
ラルフクレーバーホフ

@RalfKleberhoff確かに。新しい開発者の多くが、tripartステートメントの表現がすべてオプションであることに驚きを表明しました。私も前回のIソーを覚えていませんfor(;;)...
ロビーディー

43

forループは何か1を反復するためのものです -それらはただのlol-let-pull-some-random-stuff-the-the-the-body-and-the-the-the-the-loop-headerだけではありません-3つの式は非常に特定の意味:

  • 最初は、イテレータを初期化するためのものです。これは、インデックス、ポインタ、繰り返しオブジェクトまたは何をすることができます-限り、それがために使用される反復
  • 2番目は、最後に到達したかどうかを確認するためのものです。
  • 3番目は、イテレーターを進めるためのものです。

アイデアは、反復処理(反復方法)をループ内のロジック(各反復で行うこと)から分離することです。多くの言語には通常、反復の詳細から解放されるfor-eachループがありますが、言語にその構造がない場合や、シナリオで使用できない場合でも、ループヘッダーを制限する必要があります反復処理に。

だから、あなたは自分自身に尋ねる必要があります-反復処理またはループ内のロジックに関する条件ですか?可能性は、ループ内のロジックに関するものです。したがって、ヘッダーではなくループ内でチェックする必要があります。

1他のループとは対照的に、それは何かが起こるのを「待っています」。A for/ foreachループは、上で反復する項目の「リスト」の概念を持っている必要があります-そのリストは怠惰または無限または抽象の場合でも。


5
質問を読んだとき、これは私の最初の考えでした。残念なことに、誰かがそれを言うのを見るために半ダースの答えをスクロールしなければなりませんでした
Nemo

4
うーん... すべてのループは反復のためです-それが「反復」という言葉の意味です:-)。「コレクションの繰り返し」や「イテレータを使用した繰り返し」のようなものだと思いますか?
psmears

3
OK 答えを修正します。
イダンアリー

中間的なケースは、条件が次のようなものである場合ですsomeFunction(array[i])。条件の両方の部分は、繰り返し処理を行うものに関するもの&&であり、ループヘッダーでそれらを組み合わせることが理にかなっています。
バーマー

私はあなたの立場を尊重しますが、私は同意しません。for中心のループはリストのループではなくカウンターであり、これはfor以前の言語の構文によってサポートされていると思います(これらの言語には多くの場合、for i = 1 to 10 step 2構文とstepコマンドがあります-最初のインデックスではない初期値も許可しますelement-リストコンテキストではなく、数値コンテキストでのヒント。唯一私がサポートを考えることのユースケースforのみのリストを反復処理としてループはparallelisingであり、それは、例えば、ソートのコード実行を壊さないために、今、とにかく、明示的な構文が必要です。
ローガンピックアップ

8

でバージョンを使用することをお勧めしif (condition)ます。読みやすく、デバッグが簡単です。コードを3行追加することで問題は発生しませんが、次の人がコードを理解しやすくなります。


1
(コメントされているように)ループブロックに数百行のコードが含まれておらず、内部のロジックがロケット科学でない場合のみ。私はあなたの議論は大丈夫だと思うが、naming things何が起こっているのか、そして破壊条件がいつ満たされるのかを理解するために、適切なようなものを見逃している。
ライヴ

2
@Laivループブロックに数百行のコードがある場合、ブレーク条件をどこに書くかという問題よりも大きな問題があります。
アレクサンダー

常に真実であるとは限らないため、答えを文脈化することを提案したのはそのためです。
ライヴ

8

特定の要素をスキップするコレクションを繰り返し処理する場合は、新しいオプションをお勧めします。

  • 反復する前にコレクションをフィルタリングする

JavaとC#の両方により、これは比較的簡単になります。C ++に、当てはまらない特定の要素をスキップする派手なイテレータを作成する方法があったとしても、私は驚かないでしょう。しかし、これは実際に選択した言語がサポートしている場合のオプションにすぎず、使用してbreakいる理由は、要素を処理するかどうかの条件があるためです。

それ以外の場合、条件をforループの一部にする非常に正当な理由があります。最初の評価が正しいと仮定します。

  • ループがいつ早く終了するかを簡単に確認できます

私はforループが数百行のコードに取り組み、そこではいくつかの条件といくつかの複雑な計算が行われています。これに遭遇する問題は次のとおりです。

  • break ロジックに埋もれたコマンドは見つけるのが難しく、時々驚く
  • デバッグには、ループの各反復をステップスルーして、何が起こっているかを本当に理解する必要があります
  • 多くのコードには、簡単に元に戻せるリファクタリングや、書き換え後の機能的等価性を支援する単体テストがありません。

そのような状況で、次のガイドラインを優先順に推奨します。

  • コレクションをフィルタリングしてbreak、可能な場合の必要性を排除します
  • forループ条件の条件部分を作成します
  • break可能であれば、ループの先頭に条件文を配置します
  • ブレークに注意を引く複数行のコメントを追加し、なぜそこにあるのか

これらのガイドラインは、常にコードの正確さに従う必要があります。意図を最もよく表し、コードの明快さを改善できるオプションを選択します。


1
この答えのほとんどは問題ありません。しかし...コレクションをフィルタリングすることでcontinueステートメントの必要性を排除できることはわかりますが、コレクションがどのように役立つかはわかりませんbreak
user949300

1
@ user949300 takeWhileフィルターはbreakステートメントを置き換えることができます。あなたは1持っている場合-例えばJavaの唯一のJave 9(それはだないことでそれらを取得すること、それを自分で実装するのは難しい)
IDAN Arye

1
ただし、Javaでは、繰り返しの前にフィルタリングできます。ストリームを使用する(1.8以降)またはApacheコレクションを使用する(1.7以前)。
ライヴ

@IdanArye-そのような機能をJavaストリームAPI(例:JOO-lambda)に追加するアドオンライブラリがあります
ジュール

@IdanAryeはあなたのコメントの前にtakeWhileを聞いたことがない。フィルターを順序に明示的にリンクすると、「通常の」フィルターでは、前後に関係なくすべての要素がtrueまたはfalseを返すため、異常でハックが多いように感じます。このようにして、物事を並行して実行できます。
user949300

8

他の方法で大きな利益を得る場合を除いて、驚くことのないアプローチを取ることを強くお勧めします。

人々は単語を読むときにすべての文字を読むわけではなく、本を読むときにすべての単語を読むわけではありません。 。

そのため、たまに開発者がこれをループの単なる標準であると見なし、それを見てさえいない可能性があります。

for(int i=0;i<array.length&&!condition;i++)

関係なくそのスタイルを使用する場合は、パーツfor(int i=0;i<を変更することをお勧め;i++)します。これにより、読者の脳にこれがループの標準であることがわかります。


if- breakを使用するもう1つの理由は、for-conditionで常にアプローチを使用できるとは限らないことです。使用する必要がありますif- breakブレーク条件が複雑すぎてforステートメント内で非表示にできない場合、またはforループ内でのみアクセス可能な変数に依存している場合。

for(int i=0;i<array.length&&!((someWidth.X==17 && y < someWidth.x/2) || (y == someWidth.x/2 && someWidth.x == 18);i++)

したがって、if- を使用することにしたbreak場合は、カバーされます。ただし、for-conditionsを使用する場合は、if- breakfor-conditionsを組み合わせて使用​​する必要があります。一貫性を保つために、条件が変わるたびに条件を-conditionsと- との間で前後に移動する必要がありますforifbreak


4

変換では、ループに入るときにcondition評価さtrueれるものは何でも想定しています。定義されていないため、このインスタンスの正確性についてコメントすることはできません。

ここで「コードの行数を削減する」ことに成功したら、次に見ることができます

for(int i=0;i<array.length;i++){
    // some other code
    if(condition){
        break;
    }
    // further code
}

そして、同じ変換を適用して、

for(int i=0;i<array.length && !condition;i++){
    // some other code
    // further code
}

これは無効な変換ですfurther code。以前は無条件で実行していたので、無条件に実行します。

より安全な変換スキームは、抽出して別の関数にsome other code評価conditionすることです

bool evaluate_condition(int i) // This is an horrible name, but I have no context to improve it
{
     // some other code
     return condition;
}

for(int i=0;i<array.length && !evaluate_condition(i);i++){
    // further code
}

4

TL; DR特定の状況で最高の読み取りを行う

この例を見てみましょう:

for ( int i = 1; i < array.length; i++ ) 
{
    if(something) break;
    // perform operations
}

この場合、forループ内のコードのいずれかsomethingがtrueの場合に実行されないようにするため、テストをsomething条件フィールドに移動するのが妥当です。

for ( int i = 1; i < array.length && !something; i++ )

繰り返しますが、ループの前somethingに設定できるかどうかによって異なりtrueますが、ループ内ではない場合、これはより明確になります。

if(!something)
{
    for ( int i = 1; i < array.length; i++ )
    {...}
}

今これを想像してください:

for ( int i = 1; i < array.length; i++ ) 
{
    // perform operations
    if(something) break;
    // perform more operations
}

そこで非常に明確なメッセージを送信しています。something配列の処理中にtrueになった場合、この時点で操作全体を中止します。チェックを条件フィールドに移動するには、以下を行う必要があります。

for ( int i = 1; i < array.length && !something; i++ ) 
{
    // perform operations
    if(!something)
    {
        // perform more operations
    }
}

おそらく、「メッセージ」は濁っており、2つの場所で障害状態を確認しています。障害状態が変化し、それらの場所の1つを忘れた場合はどうでしょうか。

もちろん、forループや条件にはもっと多くの異なる形状があり、すべて独自のニュアンスがあります。

読みやすく(これは明らかに主観的です)、簡潔にコードを記述してください。厳しいガイドラインのコーディングガイドライン以外では、すべての「ルール」には例外があります。最高の意思決定を表現するものを書き、将来の間違いの可能性を最小限に抑えます。


2

ループヘッダーにすべての条件breakが表示され、大きなブロック内で混乱する可能性があるため、魅力的かもしれませんが、forループは、ほとんどのプログラマーがある程度の範囲でループすることを期待するパターンです。

特にそうするので、追加のブレーク条件を追加すると混乱が生じる可能性があり、機能的に同等であるかどうかを確認するのが難しくなります

多くの場合、配列に少なくとも1つの要素があると仮定して、両方の条件をチェックするwhileor do {} whileループを使用することをお勧めします。

int i=0
do {
    // some other code
    i++; 
} while(i < array.length && condition);

ループヘッダーからコードを実行せずに条件をチェックするだけのループを使用すると、条件がいつチェックされるか、実際の条件および副作用のあるコードが明確になります。


この質問にはすでにいくつかの良い答えがありますが、重要なポイントになるため、これを具体的に支持したかったです:私にとって、forループ(for(...; i <= n; ...))で単純な境界チェック以外のものがあると、実際にはコードが読みにくくなりますここで何が起こっているのかを止めて考えると、最初のパスで条件が完全に失われる可能性があります。私にとって、forループとは、ある範囲でループしていることを意味します。特別な終了条件がある場合は、で明示的にするifか、を使用できますwhile
CompuChip

1

コードは人間が読むことを意図しているため、これは悪いことです-非イディオマティックforループは読みにくい場合が多いため、バグはここに隠れている可能性が高くなりますが、元のコードは両方を維持しながら改善できる可能性があります短くて読みやすい。

必要なのが配列内の値を見つけることである場合(提供されているコードサンプルは多少一般的ですが、このパターンである可能性もあります)、プログラミング言語によって提供される関数を明示的に使用することができます。たとえば(プログラミング言語が指定されていないため、擬似コードは特定の言語によって解決方法が異なります)。

array.find(item -> item.valid)

これにより、必要なものが具体的にコードに示されているため、ソリューションが大幅に短縮され、簡素化されます。


1

私の意見では、そうすべきではないという理由はほとんどありません。

  1. これにより、可読性が低下します。
  2. 出力は同じでない場合があります。ただし、コードの実行後に条件がチェックされるため、do...whileループ(not while)で実行できます。

しかし、その上で、これを考慮してください、

for(int i=0;i<array.length;i++){

    // Some other code
    if(condition1){
        break;
    }

    // Some more code
    if(condition1){
        break;
    }

    // Some even more code
}

さて、これらの条件をそのfor条件に追加することで本当に達成できますか?


オープニング」とは何ですか?「意見」という意味ですか?
ピーターモーテンセン

「あなたはすべきではない、と言っているオープンのいくつかの理由」とはどういう意味ですか?詳しく説明してもらえますか?
ピーターモーテンセン

0

削除するbreakことは良い考えですが、コードの行を保存することではないでしょう。

なしで記述する利点はbreak、ループの事後条件が明白かつ明示的であることです。ループを終了してプログラムの次の行を実行すると、ループ条件i < array.length && !conditionはfalseになっているはずです。したがって、i配列の長さ以上であるか、conditiontrueです。

のバージョンにはbreak、隠れた落とし穴があります。ループ条件、有効な配列インデックスごとに他のコードを実行するとループが終了することを示していますが、実際にはbreakその前にループを終了できるステートメントがあり、ループコードを確認しない限り表示されません非常に慎重に。また、最適化コンパイラを含む自動化された静的アナライザーは、ループの事後条件も推測するのに苦労する可能性があります。

これは、エドガー・ダイクストラが「後藤は有害だ」と書いた最初の理由でした。それはスタイルの問題ではありませんでした。私はbreak;自分の人生でたくさんの声明を書きましたが、大人になってからgoto(パフォーマンスクリティカルな内部ループの複数のレベルから抜け出し、検索ツリーの別のブランチを続けるために)書きました。ただし、a returnよりも、ループから条件ステートメントを記述する可能性がはるかに高くなります(ループの後にコードを実行することはないため、後条件をマックできません)break

追記

実際、同じ動作をするようにコードをリファクタリングするには、実際にはより多くのコード行が必要になる場合があります。リファクタリングは、他の特定のコードに対して有効であるか、またはそれconditionが偽りで始まることを証明できる場合に有効です。しかし、あなたの例は一般的なケースでは次と同等です:

if ( array.length > 0 ) {
  // Some other code.
}
for ( int i = 1; i < array.length && !condition; i++ ) {
  // Some other code.
}

場合は、いくつかの他のコードは、ワンライナーではありません、あなたは、自分自身を繰り返さないように機能に移動かもしれない、とあなたは非常に近い末尾再帰関数にあなたのループをリファクタリングしました。

ただし、これはあなたの質問の主要なポイントではないことを認識しています。


問題は、ブレークがコードについて議論するのを難しくすることではなく、問題はランダムな場所でのブレークがコードを複雑なものにすることです。それが実際に必要な場合、ブレークのために議論するのは難しくありませんが、コードは複雑なことをする必要があります。
gnasher729

私が同意しない理由は次のとおりです。break文がないことがわかっていれば、ループ条件が何であるかがわかり、その条件が偽のときにループが停止することがわかります。があればbreak?次に、ループが終了する方法は複数ありますが、一般的な場合、ループの1つがいつループを停止できるかを把握することは、文字通り停止問題を解決します。実際には、私の大きな心配は、ループが1つのことをしているように見えることですが、実際には、ループが複雑なロジックに埋もれたエッジケースを見落とした後にコードを書いた人は誰でもです。ループ状態にあるものは見逃しがたいものです。
デイビスラー

0

はい。ただし、構文は型にはまらないため、bad(tm)です。

あなたの言語が次のようなものをサポートしていることを願っています

while(condition) //condition being a condition which if true you want to continue looping
{
    do thing; //your conditionally executed code goes here
    i++; //you can use a counter if you want to reference array items in order of index
}

2
多分私は私が例でまったく同じ状態を意味する文字通りそれを意味しなかった「条件」の別の単語を使用している必要があります
ユアン・

1
forループはリモートでも型破りではないだけでなく、この形式のwhileループが同等のforループよりも優れている理由はまったくありません。実際、CPPコアガイドラインの作成者
ショーンバートン

2
一部の人々は、創造的な選択肢を嫌います。または、頭の中で設定したものとは異なる方法で問題を見てください。またはより一般的には、スマートロバ。あなたの痛みを感じます!
マーティンマート

1
@seanごめんなさい、私は人々が間違っていると言われるのを嫌うことを知っていますが、私はes.77を参照します
ユアン

2
これwhileは、コード内のモンスター-ルーチン/ mundaneコードに隠されている例外を強調しています。ビジネスロジックは前面と中央にあり、ループメカニズムは包含されています。forループの選択肢に対する「ちょっと待ってください...」反応を回避します。この答えは問題を解決します。絶対に賛成票。
レーダーボブ

0

過度に複雑なfor文が読みづらいことを心配している場合、それは間違いなく有効な懸念事項です。垂直方向のスペースの浪費も問題です(それほど重要ではありませんが)。

(個人的に私は、という規則を嫌うif文は常にここ大幅に無駄な垂直スペースの原因である、中括弧を持っている必要があります。問題があることに注意してください無駄に垂直方向のスペースを。使用して問題になることはありません意味のあるラインと垂直方向のスペースを。)

1つのオプションは、複数の行に分割することです。これは間違いなくfor、複数の変数と条件を持つ本当に複雑なステートメントを使用している場合にすべきことです。(これは私にとって垂直スペースのより良い使用であり、できるだけ多くの行に意味のあるものを与えます。)

for (
   int i = 0, j = 0;
   i < array.length && !condition;
   i++, j++
) {
   // stuff
}

より良いアプローチは、より宣言的で命令性の少ない形式を使用することです。これは言語によって異なりますが、この種の機能を有効にするには独自の関数を作成する必要がある場合があります。また、condition実際に何であるかにも依存します。おそらく、配列の内容に応じて、何らかの方法で変更できる必要があります。

array
.takeWhile(condition)  // condition can be item => bool or (item, index) => bool
.forEach(doSomething); // doSomething can be item => void or (item, index) => void

複雑なまたは異常なforステートメントを複数の行に分割することは、この全体の議論で最高のアイデアです
-user949300

0

忘れられていたことが1つあります:ループを中断すると(実装方法に関係なく、可能なすべての反復を実行するわけではありません)、通常はループを終了するだけでなく、これが発生した理由も知りたいと思います。 。たとえば、アイテムXを探す場合、ループから抜けるだけでなく、Xが見つかったこととその場所も知りたいと思います。

その状況では、ループの外側に条件があるのはごく自然なことです。だから私は始めます

bool found = false;
size_t foundIndex;

そしてループで私は書きます

if (condition) {
    found = true;
    foundIndex = i;
    break;
}

forループ付き

for (i = 0; i < something && ! found; ++i)

ループ内の条件を確認するのはごく自然です。「break」ステートメントがあるかどうかは、ループ内で回避したい処理がさらにあるかどうかによって異なります。一部の処理が必要で、他の処理が必要ない場合、次のようなものがあります。

if (! found) { ... }

ループのどこかに。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.