Выход из вложенной петли - PullRequest
193 голосов
/ 28 ноября 2008

Если у меня есть цикл for, который вложен в другой, как я могу эффективно выйти из обоих циклов (внутреннего и внешнего) как можно быстрее?

Я не хочу использовать логическое значение, а затем должен сказать перейти к другому методу, а просто выполнить первую строку кода после внешнего цикла.

Какой быстрый и приятный способ сделать это?

Спасибо


Я думал, что исключения недешевы / должны создаваться только в действительно исключительном состоянии и т. Д. Поэтому я не думаю, что это решение было бы хорошим с точки зрения производительности.

Я не считаю правильным использовать новые возможности в .NET (anon-методы) для выполнения чего-то, что является довольно фундаментальным.

Из-за этого, у tvon (извините, не пишется полное имя пользователя!) Есть хорошее решение.

Марк: Хорошее использование методов anon, и это тоже замечательно, но, поскольку я могу работать, когда мы не используем версию .NET / C #, которая поддерживает методы anon, мне нужно знать и традиционный подход .

Ответы [ 20 ]

2 голосов
/ 20 декабря 2008

В зависимости от вашей ситуации, вы можете сделать это, но только если вы не выполняете код ПОСЛЕ внутреннего цикла.

for (int i = 0; i < 100; i++)
{
    for (int j = 0; j < 100; j++)
    {
        i = 100;
        break;
    }
}

Это не просто, но это может быть самым простым решением в зависимости от вашей проблемы.

2 голосов
/ 20 декабря 2008

Я видел много примеров, которые используют "break", но ни один из которых не использует "continue".

Для этого все еще потребуется флаг какого-то типа во внутреннем цикле:

while( some_condition )
{
    // outer loop stuff
    ...

    bool get_out = false;
    for(...)
    {
        // inner loop stuff
        ...

        get_out = true;
        break;
    }

    if( get_out )
    {
        some_condition=false;
        continue;
    }

    // more out loop stuff
    ...

}
1 голос
/ 28 ноября 2008

С тех пор, как пару десятилетий назад я впервые увидел break в Си, эта проблема меня раздражала. Я надеялся, что какое-то улучшение языка будет иметь расширение для прерывания, которое будет работать следующим образом:

break; // our trusty friend, breaks out of current looping construct.
break 2; // breaks out of the current and it's parent looping construct.
break 3; // breaks out of 3 looping constructs.
break all; // totally decimates any looping constructs in force.
0 голосов
/ 19 марта 2015

Как я понимаю, вы приняли ответ, в котором человек ссылается на ваше утверждение goto, где в современном программировании и, по мнению экспертов, goto является убийцей, мы назвали его убийцей в программировании, у которого есть некоторые определенные причины, которые я не буду обсуждать это здесь, на данный момент, но решение вашего вопроса очень простое, вы можете использовать булев флаг в этом сценарии, как я продемонстрирую в моем примере:

            for (; j < 10; j++)
            {
                //solution
                bool breakme = false;
                for (int k = 1; k < 10; k++)
                {
                   //place the condition where you want to stop it
                    if ()
                    {
                        breakme = true;
                        break;
                    }
                }

                if(breakme)
                    break;
               }

просто и понятно. :)

0 голосов
/ 10 сентября 2014

Создайте пользовательское исключение, которое выходит из внешнего цикла.

Работает для for, foreach или while или любого вида цикла и любого языка, который использует try catch exception block

try 
{
   foreach (object o in list)
   {
      foreach (object another in otherList)
      {
         // ... some stuff here
         if (condition)
         {
            throw new CustomExcpetion();
         }
      }
   }
}
catch (CustomException)
{
   // log 
}
0 голосов
/ 14 декабря 2013

Вы даже смотрели на ключевое слово break? O.o

Это просто псевдокод, но вы должны понимать, что я имею в виду:

<?php
for(...) {
    while(...) {
        foreach(...) {
            break 3;
        }
    }
}

Если вы думаете, что break является функцией, подобной break(), то ее параметром будет число циклов, из которых нужно выйти. Поскольку мы находимся в третьем цикле в этом коде, мы можем выйти из всех трех.

Руководство: http://php.net/break

0 голосов
/ 20 июня 2013

Я помню из моих студенческих дней, что было сказано, что математически доказуемо, что вы можете делать что-либо в коде без goto (т.е. нет ситуации, когда goto - единственный ответ) Таким образом, я никогда не использую goto's (просто мое личное предпочтение, не предполагая, что я прав или нет)

В любом случае, чтобы вырваться из вложенных циклов, я делаю что-то вроде этого:

var isDone = false;
for (var x in collectionX) {
    for (var y in collectionY) {
        for (var z in collectionZ) {
            if (conditionMet) {
                // some code
                isDone = true;
            }
            if (isDone)
                break;
        }
        if (isDone) 
            break;
    }
    if (isDone)
        break;
}

... я надеюсь, что это поможет тем, кто любит меня, против фанатов "goto" :))

0 голосов
/ 10 августа 2012
         bool breakInnerLoop=false
        for(int i=0;i<=10;i++)
        {
          for(int J=0;i<=10;i++)
          {
              if(i<=j)
                {
                    breakInnerLoop=true;
                    break;
                }
          }
            if(breakInnerLoop)
            {
            continue
            }
        }
0 голосов
/ 10 июля 2018

Вот как я это сделал. Все еще обходной путь.

foreach (var substring in substrings) {
  //To be used to break from 1st loop.
  int breaker=1;
  foreach (char c in substring) {
    if (char.IsLetter(c)) {
      Console.WriteLine(line.IndexOf(c));
      \\setting condition to break from 1st loop.
      breaker=9;
      break;
    }
  }
  if (breaker==9) {
    break;
  }
}
0 голосов
/ 28 ноября 2008

Я думаю, что если вы не хотите делать «булеву вещь», единственное решение - бросить. Что вы явно не должны делать ..!

...