web-dev-qa-db-ja.com

Objective-Cでネストされた2つのforループから抜け出すにはどうすればよいですか?

このようにネストされたforループが2つあります。

for(...) {
    for(...) {

    }
}

breakステートメントがあることを知っています。しかし、両方のループが壊れているのか、それとも呼び出されたループだけが壊れているのかについて混乱していますか?何度も繰り返すのは理にかなっていないとわかったらすぐに、両方を壊す必要があります。

74
Thanks

breakは1つのループから抜け出しますが、外側のループにチェックを追加して、内側のループが切れると切れることができます。

bool dobreak = false;
for ( ..; !dobreak && ..; .. ) {
   for ( ... ) {
      if (...) {
         dobreak = true;
         break;
      }
   }
}
92
jbasko

Gotoを使用するとコードが簡素化される場合、適切です。

for (;;) 
{
    for (;;) 
    {
        break; /* breaks inner loop */
    } 
    for (;;) 
    {
        goto outer; /* breaks outer loop */
    }
} 
outer:;
106
Ori Pessach

breakステートメントは、最も内側のループから抜け出すだけです。専用の状態変数のコード、メモリ、パフォーマンスにオーバーヘッドを追加したくない場合は、コードを独自の関数またはメソッドにリファクタリングし、returnを使用してすべてのループ:

void do_lots_of_work(void)
{
  int i, j;

  for(i=0; i<10 ; i++)
  {
    for(j=0;j< 10; j++)
    {
     ..
     ..
     if(disaster_struck())
      return; /* Gets us out of the loops, and the function too. */
    }
  }
}
14
unwind

既に述べたフラグ変数またはgoto以外に throw Objective-Cの例外があります:

@try {
  for() {
    for() {
       @throw ...
    }
  }
}
@catch{
  ...
}
9
lothar

他の人は、フラグを設定する方法やgotoを使用する方法に言及していますが、内側のループが別のメソッドに変わるようにコードをリファクタリングすることをお勧めします。そのメソッドは、外側のループがbreakである必要があることを示すフラグを返すことができます。メソッドに適切な名前を付けると、はるかに読みやすくなります。

for (int i = 0; i < 10; i++) {
   if (timeToStop(i)) break;
}

-(bool) timeToStop: (int) i {
    for (int j = 0; j < 10; j++) {
        if (somethingBadHappens) return true;
    }

    return false;
}

擬似コード、テストされていませんが、アイデアは得られます。

7
George Armhold

ブレーク前にトップループのカウンターを変更する

for(i=0; i<10 ; i++)
  for(j=0;j< 10; j++){
     ..
     ..
     i = 10; 
     break;
  }
2
oxigen

別の解決策は、関数の2番目のループを除外することです。

int i;

for(i=0; i<10 ; i++){
    if !innerLoop(i) {
        break;
    }
}

bool innerLoop(int i)
    int j;
    for(j=0;j< 10; j++){
        doSomthing(i,j);
        if(endcondtion){
            return false;
        }
    }
}
2
Martijn

Breakステートメントは、スコープ内のループ(親ループ)からのみ抜け出します。 2番目のループからも抜け出したい場合は、両方のループのスコープ内にあるブール変数を使用できます。

bool isTerminated = false;

for (...)
{
    if (!isTerminated)
    {
        for(...)
        {
            ...

            isTerminated = true;
            break;
        }
    }
    else
    {
        break;
    }
}
2
Nick Allen

おそらく最も簡単な方法は、「フラグ」変数を使用することです

for(i=0; i<10 && (done==false); i++)
  for(j=0;j< 10; j++){
     ..
     ..
     if(...){done=true; break;}
  }
2
Yogi

Breakステートメントは、最も内側のループから抜け出します。外側のループから抜け出すには、追加のテストおよびブレークステートメントが必要です。

1

ネストされたループのセット内からブレークが実行される場合、ブレークが実行される最も内側のループのみが終了します。 (標準Cと同様)

0
Mitch Wheat

にやにや笑い、このtrue/falseチェックをメソッドに変更し、returnステートメントを使用する方法は次のとおりです。

- (bool) checkTrueFalse: parameters{

   for ( ...) {
      for ( ... ) {

         if (...) {
            return true;
         }

      }
   }
   return false;
}
0
Tom Howard

最後のものとまったく同じように、一般的には次のようになります:

for(i=0;i<a;i++){  
 for(j=0;j<a;j++){
  if(Something_goes_wrong){
   i=a;
   break;
   }
 }
}
0
Martin