Phá vỡ góc cạnh ForEach


256

Tôi có một vòng lặp foreach góc và tôi muốn thoát khỏi vòng lặp nếu tôi khớp với một giá trị. Các mã sau không hoạt động.

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

Làm thế nào tôi có thể nhận được điều này?


1
Tôi không hiểu tại sao bạn không chỉ tìm thấy giá trị thay vì đi vào một vòng lặp. Có thể ví dụ bạn đưa ra không kể toàn bộ câu chuyện, nhưng tôi muốn làm những gì @Aman nói dưới đây. Tại sao đi vào vòng lặp như được đề cập dưới đây và chạy kiểm tra mỗi khi một số () thực hiện chính xác điều đó theo cách thanh lịch hơn. Hãy nhớ rằng nếu bạn coi javascript là ngôn ngữ chức năng, sẽ không có điểm nào trong việc sử dụng các cấu trúc điều khiển for / while / break này. Đó là lý do tại sao foreach, find, some, v.v ... tồn tại
Adrian Rodriguez

Câu trả lời:


264

Không có cách nào để làm điều này. Xem https://github.com/angular/angular.js/issues/263 . Tùy thuộc vào những gì bạn đang làm, bạn có thể sử dụng boolean để không đi vào phần thân của vòng lặp. Cái gì đó như:

var keepGoing = true;
angular.forEach([0,1,2], function(count){
  if(keepGoing) {
    if(count == 1){
      keepGoing = false;
    }
  }
});

45
Tôi thà chỉ thêm một !keepGoing && return;vào đầu hàm, ít mã hơn.
Andrew Joslin

46
Đây không phải là thực tiễn tốt nhất, ở đây vòng lặp forEach góc không bao giờ bị phá vỡ, VÀ không có gì để phá vỡ angular.forEach. Bản địa cho vòng lặp nhanh hơn khoảng 90% so với angular.forEach. Vì vậy, tốt hơn là sử dụng vòng lặp gốc khi bạn muốn ngắt theo điều kiện khớp. Cảm ơn
Nishchit Dhanani

xcatly nơi tôi bị mắc kẹt ... và điều này đã giúp..cảm ơn rất nhiều ... Dù sao tôi cũng muốn biết lý do khiến vòng lặp forEach không thể phá vỡ. Nếu có
Saurabh Tiwari

Đây không phải là câu trả lời được chấp nhận vì nó không phá vỡ vòng lặp forEach. Đó là một cách tốt để không thực hiện tất cả logic trong vòng lặp.
Nebulosar

296

Các angular.forEachvòng lặp không thể phá vỡ trên một trận đấu điều kiện.

Lời khuyên cá nhân của tôi là sử dụng vòng lặp NATIVE FOR thay vì angular.forEach.

Vòng lặp NATIVE FOR nhanh hơn khoảng 90% so với vòng lặp khác.

Đối với ngắt vòng, cho kết quả kiểm tra vòng lặp

SỬ DỤNG vòng lặp FOR 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
Điều này không làm việc cho tôi. Tất cả những gì nó làm là kết thúc vòng lặp đặc biệt này của vòng lặp. Nhưng sau đó nó chuyển sang lần lặp tiếp theo.
Ben

1
@Ben, Xin lỗi ben, Đó là sai lầm của tôi nhưng bây giờ tôi cập nhật câu trả lời của mình sau thời gian dài nghiên cứu. Tôi hy vọng điều này sẽ giúp bạn . Cảm ơn bạn
Nishchit Dhanani

1
@LGama: - Trường hợp của bạn là gì ??
Nishchit Dhanani

3
jsperf.com/angular-foreach-performance kiểm tra nó trên trình duyệt của riêng bạn để quyết định bạn nên chọn chức năng nào. Tôi đã thử nghiệm trên IE11 và nó cũng nhanh như trong ảnh chụp màn hình. Cũng đã thử nghiệm Array.some () nhưng chậm hơn Array.forEach () trên IE11 nhưng có thể nhanh hơn angular.foreach ;-). Hoặc kiểm tra nó ở đây jsperf.com/angular-foreach-vs-native (tất cả các khoản tín dụng thuộc về tác giả gốc, không phải tôi ;-))
Sebastian

6
Ngay cả với jsperf, bạn không thể nói "bản địa cho nhanh hơn khoảng 90%". Trong kịch bản của bạn, điều này phụ thuộc nhiều vào mức độ thực thi của hàm bên trong và mức độ thực thi có thể được lưu bằng cách thoát khỏi vòng lặp (ngắt) sớm.
hgoebl

22

vui lòng sử dụng một số hoặc mọi phiên bản của 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's expecting false to break the loop.

Ví dụ cho một số:

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

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

Ví dụ cho mọi:

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

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

Tìm thêm thông tin
http://www.jsnoob.com/2013/11/26/how-to-break-the-foreach/


không @ AngelS.Moreno, mọi người thích sử dụng biến cục bộ thay vì phương pháp được thiết kế riêng cho trường hợp trong tay
Oded Niv

18

Sử dụng một số phương thức Array

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

tồn tại sẽ trả về true và bạn có thể sử dụng điều này như một biến trong hàm của mình

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

Mảng một số phương pháp - Javascript


4
Đối với tôi, lý do duy nhất để sử dụng angular.forEach()là tôi phải hỗ trợ IE8, không có Array.forEach()... hoặc Array.some().
Bennett McElwee

2
Bạn có thể polyfill Array.forEach dễ dàng. Xem dưới cùng của trang: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Kẻ

6

Theo như tôi biết, Angular không cung cấp chức năng như vậy. Bạn có thể muốn sử dụng find()chức năng gạch dưới cho việc này (về cơ bản là forEach sẽ thoát ra khỏi vòng lặp một khi hàm trả về đúng).

http://underscorejs.org/#find


điều này có thể giải quyết vấn đề về sau, nhưng nó không thực sự phá vỡ vòng lặp.
Elise Chant

Hoặc bản địa cho vòng lặp
shanti

6

Nếu bạn sử dụng jQuery (do đó không phải là jqLite) kết hợp với AngularJS, bạn có thể lặp lại với $ .each - cho phép ngắt và tiếp tục dựa trên biểu thức giá trị trả về boolean.

Mã thông báo:

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
    }
});

Ghi chú:

Mặc dù sử dụng jQuery không phải là xấu, cả hai hàm Array.some hoặc Array.every đều được MDN khuyên dùng vì bạn có thể đọc tại tài liệu forEach gốc :

"Không có cách nào để dừng hoặc phá vỡ vòng lặp forEach. Giải pháp là sử dụng Array.every hoặc Array.some"

Các ví dụ sau được MDN cung cấp:

Mảng

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

Cụ thể, bạn có thể thoát khỏi một forEachvòng lặp, và ở bất kỳ nơi nào, ném một ngoại lệ.

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

Tuy nhiên, sẽ tốt hơn nếu bạn sử dụng thư viện khác hoặc thực hiện chức năng của riêng bạn, một findchức năng trong trường hợp này, vì vậy mã của bạn là cấp cao nhất.


10
Vâng, bạn đã trả lời câu hỏi! Tôi hy vọng không ai làm điều đó mặc dù :)
Jason Cox

Ném một ngoại lệ không cần thiết là cách xử lý tình huống không tốt. Thay vào đó, hãy kiểm tra giải pháp được cung cấp bởi @ dnc253 stackoverflow.com/a/13844508/698127
Aamol

4

Hãy thử điều này như phá vỡ;

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

3

Như các câu trả lời khác, Angular không cung cấp chức năng này. Tuy nhiên, jQuery có và nếu bạn đã tải jQuery cũng như Angular, bạn có thể sử dụng

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

Xem http://api.jquery.com/jquery.each/


2
OP đã yêu cầu một giải pháp AngularJS, câu trả lời đúng là KHÔNG :)
Shannon Hochkins

3

Thông thường không có cách nào để phá vỡ một vòng lặp "mỗi" trong javascript. Những gì có thể được thực hiện thường là sử dụng phương pháp "ngắn mạch".

    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.')
    }


2

break không thể đạt được trong forEach góc, chúng ta cần sửa đổi forEach để làm điều đó.

$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
                  }
                });

Câu trả lời này dường như không đầy đủ. Vui lòng cho biết liệu break()cần phải được xác định hoặc wether nó đã là một phần của góc. Hãy xác định nếu không.
địa lý

2

Bạn có thể sử dụng điều này:

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

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
$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;
     });
 }

0

Tôi muốn làm điều này bằng cách trở lại. Đặt phần lặp trong chức năng riêng tư và quay lại khi bạn muốn phá vỡ vòng lặp.


0

Tôi nhận ra điều này đã cũ, nhưng một bộ lọc mảng có thể làm những gì bạn cần:

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

Sau đó bạn có thể chạy arr.forEachvà các chức năng mảng khác.

Tôi nhận ra rằng nếu bạn có ý định cắt giảm hoàn toàn các hoạt động vòng lặp, điều này có thể sẽ không làm những gì bạn muốn. Cho rằng bạn sử dụng tốt nhất while.


0

Ví dụ này hoạt động. Thử nó.

var array = [0,1,2];
for( var i = 0, ii = array.length; i < ii; i++){
  if(i === 1){
   break;
  }
}

1
Tôi đoán rằng anh ta không muốn một forvòng lặp, trường hợp sử dụng của anh ta không cần foreachphải forcó lẽ
Hassen Ch.

0

Sử dụng Return để phá vỡ vòng lặp.

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

0
onSelectionChanged(event) {
    let selectdata = event['api']['immutableService']['gridOptionsWrapper']['gridOptions']['rowData'];
    let selected_flag = 0;

    selectdata.forEach(data => {
      if (data.selected == true) {
        selected_flag = 1;
      }
    });

    if (selected_flag == 1) {
      this.showForms = true;
    } else {
      this.showForms = false;
    }
}

-1

Tôi sẽ sử dụng returnthay vì break.

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

Hoạt động như một lá bùa.


đây không phải là một giải pháp hợp lệ look: function test () {angular.forEach ([1,2,3,4,5,6,7,8,9], function (value, index) {if (value == 2) return; console.log (giá trị);})} đầu ra:> teste (); 1 3 4 5 6 7 8 9
otaviodecampos

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.