Угловой JS break ForEach

254

У меня есть цикл angular foreach, и я хочу выйти из цикла, если я соответствует значению. Следующий код не работает.

angular.forEach([0,1,2], function(count){
  if(count == 1){
    break;
  }
});

Как я могу это получить?

  • 1
    Я не понимаю, почему вы не просто находите значение, а не зацикливаетесь. Возможно, приведенный вами пример не рассказывает всей истории, но я бы лучше сделал то, что сказал @Aman ниже. Зачем идти в цикл, как указано ниже, и запускать проверку каждый раз, когда some () делает это более элегантным способом. Помните, что если вы рассматриваете javascript как функциональный язык, не должно быть смысла использовать их для управляющих структур типа / while / break. Вот почему существуют foreach, find, some и др.
Теги:
javascript-framework

19 ответов

239
Лучший ответ

Нет никакого способа сделать это. См. https://github.com/angular/angular.js/issues/263. В зависимости от того, что вы делаете, вы можете использовать логическое значение, чтобы просто не попасть в тело цикла. Что-то вроде:

var keepGoing = true;
angular.forEach([0,1,2], function(count){
  if(keepGoing) {
    if(count == 1){
      keepGoing = false;
    }
  }
});
  • 43
    Я бы предпочел просто добавить !keepGoing && return; к началу функции, меньше кода.
  • 43
    Это не лучшая практика, здесь угловой цикл forEach никогда не прерывается, и нет ничего, что могло бы нарушить angular.forEach. Собственный цикл for примерно на 90% быстрее, чем angular.forEach. Поэтому лучше использовать native for loop, если вы хотите прервать соответствие условия. Спасибо
Показать ещё 2 комментария
298

Цикл angular.forEach не может сломаться при совпадении условий.

Мой личный совет - использовать цикл NATIVE FOR вместо angular.forEach.

Цикл NATIVE FOR находится вокруг 90% быстрее, чем другие для циклов.

Изображение 3666

ИСПОЛЬЗОВАТЬ FOR loop IN ANGULAR:

var numbers = [0, 1, 2, 3, 4, 5];

for (var i = 0, len = numbers.length; i < len; i++) {
  if (numbers[i] === 1) {
    console.log('Loop is going to break.'); 
    break;
  }
  console.log('Loop will continue.');
}
  • 1
    Это не работает для меня. Все, что он делает, это заканчивает эту конкретную итерацию цикла. Но затем он переходит к следующей итерации.
  • 1
    @ Бен, прости Бен, это была моя ошибка, но теперь я обновляю свой ответ после долгих исследований. Я надеюсь, что это поможет вам . Спасибо
Показать ещё 9 комментариев
23

используйте некоторые или все экземпляры ForEach,

Array.prototype.some:
some is much the same as forEach but it break when the callback returns true

Array.prototype.every:
every is almost identical to some except it expecting false to break the loop.

Пример для некоторых:

var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];

ary.some(function (value, index, _ary) {
    console.log(index + ": " + value);
    return value === "JavaScript";
});

Пример для каждого:

var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];

ary.every(function(value, index, _ary) {
    console.log(index + ": " + value);
    return value.indexOf("Script") > -1;
});

Найти больше информации
http://www.jsnoob.com/2013/11/26/how-to-break-the-foreach/

  • 0
    нет @ AngelS.Moreno, все предпочитают использовать локальную переменную вместо метода, разработанного специально для данного случая
17

Использовать метод массива

 var exists = [0,1,2].some(function(count){
      return count == 1
 });

exists вернет true, и вы можете использовать это как переменную в своей функции

if(exists){
    console.log('this is true!')
}

Array Some Method - Javascript

  • 4
    Для меня единственной причиной использования angular.forEach() является то, что я должен поддерживать IE8, у которого нет Array.forEach() ... или Array.some() .
  • 2
    Вы можете легко заполнить Array.forEach. См. Внизу страницы: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
6

Конкретно, вы можете выйти из цикла forEach и любого места, выбросить исключение.

try {
   angular.forEach([1,2,3], function(num) {
      if (num === 2) throw Error();
   });
} catch(e) {
    // anything
}

Однако, если вы используете другую библиотеку или реализуете свою собственную функцию, функция find в этом случае, поэтому ваш код является наиболее высокоуровневым.

  • 8
    Ну, вы ответили на вопрос! Я надеюсь, что никто не делает этого, хотя :)
  • 0
    Излишнее исключение - плохой способ справиться с ситуацией. Скорее проверьте решение, предоставленное @ dnc253 stackoverflow.com/a/13844508/698127
6

Если вы используете jQuery (следовательно, не jqLite) в сочетании с AngularJS, вы можете выполнять итерации с $.each - что позволяет ломать и продолжать на основе выражения логического возвращаемого значения.

JSFiddle:

http://jsfiddle.net/JEcD2/1/

Javascript:

var array = ['foo', 'bar', 'yay'];
$.each(array, function(index, element){
    if (element === 'foo') {
        return true; // continue
    }
    console.log(this);
    if (element === 'bar') {
        return false; // break
    }
});

Замечания:

Хотя использование jQuery неплохо, MDN рекомендует использовать как нативные функции Array.some, так и Array.every, поскольку вы можете прочитать в нативной документации forEach:

"Невозможно остановить или прервать цикл forEach. Решение - использовать Array.every или Array.some"

Следующие примеры предоставлены MDN:

Array.some:

function isBigEnough(element, index, array){
    return (element >= 10);
}
var passed = [2, 5, 8, 1, 4].some(isBigEnough);
// passed is false
passed = [12, 5, 8, 1, 4].some(isBigEnough);
// passed is true

Array.every:

function isBigEnough(element, index, array){
    return (element >= 10);
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);
// passed is false
passed = [12, 54, 18, 130, 44].every(isBigEnough);
// passed is true
6

Насколько я знаю, Angular не предоставляет такую ​​функцию. Вы можете использовать функцию подчеркивания find() для этого (в основном это forEach, которая выходит из цикла после возвращения функции true).

http://underscorejs.org/#find

  • 0
    это может решить проблему в боковом направлении, но на самом деле это не нарушает петлю.
  • 0
    Или родной для цикла
3

Обычно нет возможности разбить "каждый" цикл в javascript. Обычно можно использовать метод "короткого замыкания".

    array.forEach(function(item) {
      // if the condition is not met, move on to the next round of iteration.
      if (!condition) return;

      // if the condition is met, do your logic here
      console.log('do stuff.')
    }
3

Как утверждают другие ответы, Angular не предоставляет эту функцию. Однако jQuery, и если вы загрузили jQuery, а также Angular, вы можете использовать

jQuery.each ( array, function ( index, value) {
    if(condition) return false; // this will cause a break in the iteration
})

См. http://api.jquery.com/jquery.each/

  • 2
    ОП попросил решение AngularJS, правильный ответ - НЕТ :)
2

Вы можете использовать это:

var count = 0;
var arr = [0,1,2];
for(var i in arr){
   if(count == 1) break;
   //console.log(arr[i]);
}
2

break невозможно достичь в angular forEach, нам нужно изменить forEach для этого.

$scope.myuser = [{name: "Ravi"}, {name: "Bhushan"}, {name: "Thakur"}];  
                angular.forEach($scope.myuser, function(name){
                  if(name == "Bhushan") {
                    alert(name);
                    return forEach.break(); 
                    //break() is a function that returns an immutable object,e.g. an empty string
                  }
                });
  • 0
    Этот ответ не кажется полным. Пожалуйста, укажите, нужно ли определять break() или он уже является частью angular. Пожалуйста, определите, если нет.
1

Попробуйте это как break;

angular.forEach([0,1,2], function(count){
  if(count == 1){
    return true;
  }
});
1
var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];
var keepGoing = true;
ary.forEach(function(value, index, _ary) {
    console.log(index)
    keepGoing = true;
    ary.forEach(function(value, index, _ary) {
        if(keepGoing){ 
            if(index==2){
                keepGoing=false;
            }
            else{
                console.log(value)
            }

        }      
    });
});
0

Я бы использовал return вместо break.

angular.forEach([0,1,2], function(count){
  if(count == 1){
    return;
  }
});

Работает как шарм.

  • 0
    это не правильное решение. look: function test () {angular.forEach ([1,2,3,4,5,6,7,8,9], function (value, index) {if (value == 2) return; console.log (значение);})} output:> teste (); 1 3 4 5 6 7 8 9
0

Я понимаю, что это старый, но фильтр массива может делать то, что вам нужно:

var arr = [0, 1, 2].filter(function (count) {
    return count < 1;
});

Затем вы можете запустить arr.forEach и другие функции массива.

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

0

Этот пример работает. Попробуйте.

var array = [0,1,2];
for( var i = 0, ii = array.length; i < ii; i++){
  if(i === 1){
   break;
  }
}
  • 1
    Я думаю, что он не хочет цикл for , его foreach использования нуждается в foreach не for вероятно,
0

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

0
$scope.arr = [0, 1, 2];  
$scope.dict = {}
for ( var i=0; i < $scope.arr.length; i++ ) {
    if ( $scope.arr[i] == 1 ) {
        $scope.exists = 'yes, 1 exists';
        break;
    }
 }
 if ( $scope.exists ) {
     angular.forEach ( $scope.arr, function ( value, index ) {
                      $scope.dict[index] = value;
     });
 }
-2

Просто добавьте $index и выполните следующие действия:

angular.forEach([0,1,2], function(count, $index) {
     if($index !== 1) {
          // do stuff
     }
}
  • 0
    ОП хочет вырваться из цикла.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню