Javascript для прерывания цикла [дубликат]

Это может быть альтернатива:

$className = '%' . $this->className . '%';
$query->bind_param('s', $className);
307
задан webeno 10 March 2016 в 09:33
поделиться

13 ответов

Также как Perl,

loop1:
    for (var i in set1) {
loop2:
        for (var j in set2) {
loop3:
            for (var k in set3) {
                break loop2;  // breaks out of loop3 and loop2
            }
        }
    }

, как определено в разделе 12.12 EMCA-262. [MDN Docs]

В отличие от C эти метки могут использоваться только для continue и break , поскольку Javascript не имеет goto.

730
ответ дан Pavel 18 August 2018 в 22:22
поделиться
  • 1
    @NielsBom Вы правы: он выходит из цикла с данной меткой. Это не goto ярлык. Вы, по сути, называете цикл и говорите, что я хочу вырваться из такого цикла. – devios1 31 May 2012 в 22:50
  • 2
    WTF, почему я не видел, чтобы это использовалось где-то за 3 года с JavaScript: / .. – Salman Abbas 21 July 2012 в 19:17
  • 3
    MDN говорит «избегать использования меток». чисто по соображениям удобочитаемости. Почему это не «читаемо»? Конечно, никто их не использует. Но почему они не используют их? ... – XML 2 May 2014 в 21:43
  • 4
    @SeantheBean Сделано. Это похоже на более простой ответ и не открывается для злоупотреблений, потому что он доступен только для continue и break. – Gary Willoughby 12 November 2015 в 22:17
  • 5
    @ JérémyPouyet - Ваша логика для голосования вниз является безупречной и необоснованной. Он отлично отвечает на вопрос OP. Вопрос не связан с вашими мнениями относительно удобочитаемости. Пожалуйста, пересмотреть свой подход к оказанию помощи сообществу. – The Dembinski 16 January 2017 в 21:01

Я немного опаздываю на вечеринку, но следующий язык - агностический подход, который не использует GOTO / ярлыки или обертывание функций:

for (var x = Set1.length; x > 0; x--)
{
   for (var y = Set2.length; y > 0; y--)
   {
      for (var z = Set3.length; z > 0; z--)
      {
          z = y = -1; // terminates second loop
          // z = y = x = -1; // terminate first loop
      }
   }
}

. Поверхность протекает естественно, что должен понравиться толпе не-GOTO. С другой стороны, внутренний цикл должен завершить текущую итерацию до завершения, чтобы в некоторых сценариях она не применима.

67
ответ дан aleemb 18 August 2018 в 22:22
поделиться
  • 1
    открывающая скобка не должна быть на новых строках, так как js-реализации могут вставить двоеточие в конце предыдущей строки. – Evgeny 20 September 2012 в 20:07
  • 2
    @Evgeny: в то время как некоторые руководства по стилю JavaScript требуют, чтобы открытые фигурные скобки выполнялись в одной строке, неверно иметь его на новой строке, и нет никакой опасности, что интерпретатор неоднозначно вставляет точку с запятой. Поведение ASI хорошо определено и не применяется здесь. – Jason Suárez 6 March 2013 в 11:25
  • 3
    Просто не забудьте прокомментировать этот подход. Не сразу видно, что здесь происходит. – Qix 4 November 2014 в 17:02
  • 4
    Хороший и простой ответ. Это следует рассматривать как ответ, поскольку он не напрягает интенсивные циклы процессора (что является проблемой с использованием функций) или не использует метки, которые обычно не читаются или не должны использоваться, как говорят некоторые. :) – Girish Sortur 9 November 2015 в 19:09
  • 5
    Возможно, мне что-то не хватает, но чтобы обойти проблему внутреннего цикла, чтобы завершить эту итерацию, вы могли бы поставить break или continue сразу после установки z и y? Мне нравится идея использовать условия цикла for для выхода. Элегантный по-своему. – Ben Sutton 7 December 2015 в 19:01

Оберните это в функцию, а затем просто return.

124
ответ дан CloudyMarble 18 August 2018 в 22:22
поделиться
  • 1
    Я решил принять этот ответ, потому что он прост и может быть выполнен в элегантном стиле. Я абсолютно ненавижу GOTO и считаю их плохой практикой ( может открывать ), Ephemient слишком близко к одному. ; О) – Gary Willoughby 8 October 2008 в 21:05
  • 2
    ИМО, GOTO прекрасно, если они не нарушают структурирование. Но каждому свое! – ephemient 10 October 2008 в 21:09
  • 3
    Ярлыки для циклов имеют абсолютно ничего вместе с GOTO, за исключением их синтаксиса. Им просто нужно сломаться от внешних петель. У вас нет проблем с нарушением самого внутреннего цикла, не так ли? так почему у вас есть проблема с нарушением внешних петель? – John Smith 15 March 2014 в 17:12
  • 4
    Пожалуйста, подумайте о принятии другого ответа. Если бы не Андрей Андреевский комментарий (спасибо кстати), я бы подумал: ах, поэтому у javascript нет этой функции. И я уверен, многие в сообществе могут игнорировать комментарий и думать точно так же. – John Smith 15 March 2014 в 22:38
  • 5
    Почему у Stack Overflow нет функции, позволяющей сообществу отменить явно неправильный выбранный ответ? : / – Matt Huggins 27 August 2014 в 00:40

лучший способ - 1) Сортировка обоих массивов, которые используются в первом и втором циклах. 2) если элемент согласован, то разбить внутренний цикл и удерживать значение индекса. 3) при запуске следующей итерации запустите внутренний цикл с индексом удержания.

-4
ответ дан Deepak Karma 18 August 2018 в 22:22
поделиться

Как об использовании каких-либо разрывов вообще, никаких флажков отмены и никаких дополнительных проверок условий. Эта версия просто взрывает переменные цикла (делает их Number.MAX_VALUE), когда условие встречается, и заставляет все петли прекращать элегантно.

// No breaks needed
for (var i = 0; i < 10; i++) {
  for (var j = 0; j < 10; j++) {
    if (condition) {
      console.log("condition met");
      i = j = Number.MAX_VALUE; // Blast the loop variables
    }
  }
}

Был найден аналогичный ответ для вложенного типа типа декрементирования петли, но это работает для вложенных циклов инкрементного типа, не требуя рассмотрения значения конца цикла для простых циклов.

Другой пример:

// No breaks needed
for (var i = 0; i < 89; i++) {
  for (var j = 0; j < 1002; j++) {
    for (var k = 0; k < 16; k++) {
      for (var l = 0; l < 2382; l++) {
        if (condition) {
          console.log("condition met");
          i = j = k = l = Number.MAX_VALUE; // Blast the loop variables
        }
      }
    }
  }
}
12
ответ дан Drakes 18 August 2018 в 22:22
поделиться
var str = "";
for (var x = 0; x < 3; x++) {
    (function() {  // here's an anonymous function
        for (var y = 0; y < 3; y++) {
            for (var z = 0; z < 3; z++) {
                // you have access to 'x' because of closures
                str += "x=" + x + "  y=" + y + "  z=" + z + "<br />";
                if (x == z && z == 2) {
                    return;
                }
            }
        }
    })();  // here, you execute your anonymous function
}

Как это? :)

35
ответ дан harley.333 18 August 2018 в 22:22
поделиться
  • 1
    Я подумал, что это то, что получал swilliams – harley.333 8 October 2008 в 21:13
  • 2
    Это добавляет значительную стоимость исполнения, если цикл является большим - новый контекст выполнения для этой функции должен быть создан (и в какой-то момент освобожден GC) с помощью интерпретатора / компилятора Javascript (или, «compreter» в эти дни, сочетание обоих ) КАЖДЫЙ РАЗ. – Mörre 18 October 2011 в 13:29
  • 3
    Это на самом деле довольно опасно, потому что могут произойти некоторые странные вещи, которых вы не ожидаете. В частности, из-за закрытия, созданного с помощью var x, если какая-либо логика в цикле ссылается на x в более поздний момент времени (например, она определяет внутреннюю анонимную функцию, которая сохраняется и выполняется позже), значение для x будет быть тем, что было в конце цикла end , а не индексом, который была определена во время. (Продолжение) – devios1 31 May 2012 в 22:57
  • 4
    – devios1 31 May 2012 в 22:57
  • 5

Если вы используете Coffeescript, есть удобное ключевое слово «сделать», которое упрощает определение и немедленно выполняет анонимную функцию:

do ->
  for a in first_loop
    for b in second_loop
      if condition(...)
        return

... поэтому вы можете просто использовать «возврат», чтобы выйти из петель.

3
ответ дан Nick Perkins 18 August 2018 в 22:22
поделиться
  • 1
    Это не одно и то же. В моем исходном примере три петли for не две. – Gary Willoughby 19 July 2017 в 20:23
XXX.Validation = function() {
    var ok = false;
loop:
    do {
        for (...) {
            while (...) {
                if (...) {
                    break loop; // Exist the outermost do-while loop
                }
                if (...) {
                    continue; // skips current iteration in the while loop
                }
            }
        }
        if (...) {
            break loop;
        }
        if (...) {
            break loop;
        }
        if (...) {
            break loop;
        }
        if (...) {
            break loop;
        }
        ok = true;
        break;
    } while(true);
    CleanupAndCallbackBeforeReturning(ok);
    return ok;
};
-3
ответ дан Triqui 18 August 2018 в 22:22
поделиться
  • 1
    Это выглядит более запутанным, чем оригинал. – Cristiano Fontes 11 October 2012 в 12:11
  • 2
    Как постмодернистская поэма – Digerkam 14 May 2013 в 09:51
  • 3
    Проголосовало за то, что в то время как в большинстве случаев это становится более привычным. – Cody 9 September 2013 в 15:49

довольно просто

var a=[1,2,3];
var b=[4,5,6];
var breakCheck1=false;

for (var i in a){
    for (var j in b){
        breakCheck1=true;
        break;
    }
    if (breakCheck1) {break;}
}
32
ответ дан user 18 August 2018 в 22:22
поделиться
  • 1
    Я согласен, что это на самом деле самое лучшее, функция не масштабируется, обертывая все для циклов, если также не масштабируется, то есть затрудняет чтение и отладку ... это потрясающе. Вы можете просто объявить vars loop1, loop2, loop3 и добавить небольшую инструкцию в конце. Также, чтобы разбить несколько циклов, вам нужно будет сделать что-то вроде loop1=loop2=false; – Muhammad Umer 9 April 2015 в 04:30

Как насчет нажатия петель до их конечных пределов

    for(var a=0; a<data_a.length; a++){
       for(var b=0; b<data_b.length; b++){
           for(var c=0; c<data_c.length; c++){
              for(var d=0; d<data_d.length; d++){
                 a =  data_a.length;
                 b =  data_b.length;
                 c =  data_b.length;
                 d =  data_d.length;
            }
         }
       }
     }
2
ответ дан user889030 18 August 2018 в 22:22
поделиться

Я знаю, что это было спрошено 8 лет назад, но в ES6 мы получили цикл для ... , который позволяет использовать стандартные функции прерывания:

for (let item of items) {
  if (item.id === id) {
    //do something cool
    break;
  }
}
-5
ответ дан vladexologija 18 August 2018 в 22:22
поделиться
  • 1
    Итак, как вы выходите из двух таких петель? В этом весь вопрос. – Gary Willoughby 19 July 2017 в 20:22

Я думал, что покажу функционально-программирующий подход. Вы можете вырваться из вложенных функций Array.prototype.some () и / или Array.prototype.every (), как в моих решениях. Дополнительным преимуществом этого подхода является то, что Object.keys() перечисляет только собственные перечислимые свойства объекта, тогда как «for-in loop также перечисляет свойства в цепочке прототипов» .

Близко к решению OP:

    Args.forEach(function (arg) {
        // This guard is not necessary,
        // since writing an empty string to document would not change it.
        if (!getAnchorTag(arg))
            return;

        document.write(getAnchorTag(arg));
    });

    function getAnchorTag (name) {
        var res = '';

        Object.keys(Navigation.Headings).some(function (Heading) {
            return Object.keys(Navigation.Headings[Heading]).some(function (Item) {
                if (name == Navigation.Headings[Heading][Item].Name) {
                    res = ("<a href=\""
                                 + Navigation.Headings[Heading][Item].URL + "\">"
                                 + Navigation.Headings[Heading][Item].Name + "</a> : ");
                    return true;
                }
            });
        });

        return res;
    }

Решение, которое уменьшает итерацию над заголовками / элементами:

    var remainingArgs = Args.slice(0);

    Object.keys(Navigation.Headings).some(function (Heading) {
        return Object.keys(Navigation.Headings[Heading]).some(function (Item) {
            var i = remainingArgs.indexOf(Navigation.Headings[Heading][Item].Name);

            if (i === -1)
                return;

            document.write("<a href=\""
                                         + Navigation.Headings[Heading][Item].URL + "\">"
                                         + Navigation.Headings[Heading][Item].Name + "</a> : ");
            remainingArgs.splice(i, 1);

            if (remainingArgs.length === 0)
                return true;
            }
        });
    });
2
ответ дан Zachary Ryan Smith 18 August 2018 в 22:22
поделиться

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

var a, b, abort = false;
for (a = 0; a < 10 && !abort; a++) {
    for (b = 0; b < 10 && !abort; b++) {
        if (condition) {
            doSomeThing();
            abort = true;
        }
    }
}
59
ответ дан zord 18 August 2018 в 22:22
поделиться
  • 1
    Если condition оценивает true на первой итерации вложенного цикла, вы все равно выполняете оставшуюся часть из 10 итераций, каждый раз проверяя значение abort. Это не проблема производительности для 10 итераций, но это будет, скажем, 10 000. – Robusto 2 December 2013 в 16:53
  • 2
    Нет, он выходит из обоих циклов. Вот демонстрационный скрипт . Независимо от того, какое условие вы устанавливаете, оно выходит после его выполнения. – zord 2 December 2013 в 22:13
  • 3
    Оптимизация будет заключаться в добавлении перерыва; после установки abort = true; и удаление! прекратить проверку состояния из конечного цикла. – xer21 20 September 2016 в 15:43
  • 4
    Мне это нравится, но я думаю, что в общем случае вы сделали бы много ненужной обработки, то есть для каждой итерации каждого итератора evalueate abort и выражения. В простых сценариях, которые могут быть прекрасными, но для огромных циклов с gazillion итерациями, которые могут быть проблемой – Z. Khullah 11 December 2017 в 18:08
  • 5
    Еще один приятный язык-агностический подход, хотя и менее нюансный, чем тот, который выше, что позволяет ломать любой из вложенных циклов. – Kim 25 April 2018 в 14:55
Другие вопросы по тегам:

Похожие вопросы: