2009-12-11 60 views
11

tôi cảm thấy bẩn mỗi khi tôi "phá vỡ" ra khỏi một for-each xây dựng (PHP/Javascript)cho mỗi ... phá vỡ

Vì vậy, một cái gì đó như thế này:

// javascript dụ

for (object in objectList) 
{ 
    if (object.test == true) 
    { 
     //do some process on object 
     break; 
    } 

} 

Đối với đối tượng lớn, tôi sẽ giải quyết vấn đề này một cách đơn giản hơn. Nhưng đối với các danh sách nhỏ không có vấn đề hiệu suất đáng chú ý và do đó "tại sao không?" Thật nhanh chóng và quan trọng hơn là dễ hiểu và dễ hiểu.

Nhưng nó chỉ "cảm thấy sai". Loại giống như một tuyên bố goto.

Bạn xử lý loại tình huống này như thế nào?

+0

Tôi biết những gì bạn đang nói, nhưng mọi người đi đúng hướng - ngắt là tốt, đặc biệt là đối với các danh sách nhỏ. Danh sách lớn của tôi thường là từ các truy vấn DB và nếu tôi phải sử dụng hàm LIMIT ở đó để chỉ lấy một tập hợp con các bản ghi. Câu trả lời ngắn - không cảm thấy xấu về việc sử dụng "break" hoặc "continue" – jbnunn

+0

Mã của bạn sẽ không hoạt động theo cách này bởi vì toán tử for..in sẽ luôn lặp qua các khóa (chuỗi) của đối tượng. Bạn có thể có ý nghĩa như sau: cho (var key trong objectList) { var object = objectList [key]; ... } –

Trả lời

27

Tôi sử dụng ngắt. Đó là một giải pháp hoàn hảo.

+16

+1 để sử dụng từ "cromulent". –

+0

'cromulent'! Tôi thích nó –

+0

Những gì tôi thích về "cromulent" là nó có nghĩa là nó là gì - một từ hoàn toàn rõ ràng ý nghĩa của nó từ ngữ cảnh. –

1

Tôi thực sự không thấy bất kỳ điều gì sai trái khi vi phạm vòng lặp for. Trừ khi bạn có một số loại bảng băm, từ điển mà bạn có một số loại chìa khóa để có được một giá trị thực sự không có cách nào khác.

1

Tôi muốn sử dụng câu lệnh break.

2

Đối với các danh sách nhỏ, không có vấn đề gì khi thực hiện việc này. Như bạn đề cập, bạn có thể muốn suy nghĩ về một giải pháp 'thanh lịch' hơn cho các danh sách lớn (đặc biệt là các danh sách có kích thước không xác định).

Thỉnh thoảng nó cảm thấy sai, nhưng không sao cả. Bạn sẽ học cách yêu thích break trong thời gian.

+0

Tôi không biết .... Tôi đã lập trình được khoảng 15 năm. Tôi làm điều đó (sử dụng break), nó chỉ có vẻ như gian lận đôi khi .... – ChronoFish

2

Như bạn đã nói "" tại sao không? "Thật nhanh chóng và quan trọng hơn là dễ hiểu và dễ hiểu".

Tại sao cảm thấy bẩn, tôi thấy không có gì sai với điều này.

2

Tôi nghĩ là dễ đọc hơn và do đó dễ bảo trì hơn.

2

Nó có nghĩa là giống như vậy. Break được thiết kế để nhảy ra khỏi vòng lặp. Nếu bạn đã tìm thấy những gì bạn cần trong một vòng lặp tại sao giữ cho vòng lặp đi?

0

Có lẽ tôi hiểu nhầm trường hợp sử dụng của bạn, nhưng tại sao lại bị phá vỡ? Tôi giả sử bạn đang mong đợi thử nghiệm là đúng cho nhiều nhất một phần tử trong danh sách?

Nếu không có vấn đề về hiệu suất và bạn muốn xóa mã, bạn luôn có thể bỏ qua thử nghiệm và ngắt.

for (object in objectList) 
{ 
    //do some process on object 
} 

Bằng cách đó, nếu bạn cần thực hiện quy trình trên nhiều phần tử, mã của bạn sẽ không bị phá vỡ (chơi có chủ ý).

+0

Tôi sẽ chỉ phá vỡ các trường hợp mà tôi muốn tìm mục đầu tiên (hoặc duy nhất) để phù hợp với điều khoản thử nghiệm của tôi. Đơn giản chỉ cần để cho vòng lặp tiếp tục chỉ là chu trình cháy trong những trường hợp này. – ChronoFish

+0

Nó phụ thuộc vào việc bạn quan tâm nhiều hơn đến việc đốt cháy chu trình não hay chu kỳ CPU. Breaking là một tối ưu hóa - nó có thể là một trong những hợp lý nhưng nếu danh sách là nhỏ, sau đó xem xét để lại nó ra cho đến khi bạn biết bạn cần nó. – ctford

0

Tùy chọn của tôi chỉ đơn giản là sử dụng break. Nó nhanh chóng và thường không phức tạp.

Nếu bạn sử dụng một for, while, hoặc do while vòng lặp, bạn có thể sử dụng một biến để xác định có hay không để tiếp tục:

for ($i = 0, $c = true; ($i < 10) && $c; $i++) { 
    // do stuff 

    if ($condition) { 
     $c= false; 
    } 
} 

Cách duy nhất để phá vỡ từ một vòng lặp foreachbreak hoặc return .

+0

Tôi làm điều này, mặc dù thường chỉ với một vòng lặp 'while'. – Tenner

+4

Vì vậy, bạn muốn thêm một cờ, năm dòng, và '&& 'hơn' ngắt;'? – Tordek

+0

-1 điều này là không có lợi ích – JonH

5

Thật nhanh chóng và quan trọng hơn là dễ hiểu và dễ hiểu.

Đừng cảm thấy xấu về nghỉ. Goto được tán thành vì nó nhanh chóng và quan trọng hơn là không phải là dễ hiểu và dễ hiểu.

2

Điểm dừng và tiếp tục không phải là ảnh. Họ ở đó vì một lý do. Ngay khi bạn hoàn thành cấu trúc vòng lặp, hãy thoát khỏi vòng lặp.

Bây giờ, những gì tôi sẽ tránh là làm tổ rất sâu (a.k.a. chống mẫu thiết kế đầu mũi tên).

if (someCondition) 
{ 
    for (thing in collection) 
    { 
     if (someOtherCondition) 
     { 
      break; 
     } 
    } 
} 

Nếu bạn định nghỉ ngơi, hãy đảm bảo rằng bạn đã cấu trúc mã của mình để mã đó chỉ sâu một lần. Sử dụng các cuộc gọi hàm để giữ cho lặp lại càng nông càng tốt.

if (someCondition) 
{ 
    loopThroughCollection(collection); 
} 

function loopThroughCollection(collection) 
{ 
    for (thing in collection) 
    { 
     if (someOtherCondition) 
     { 
      doSomethingToObject(thing); 
      break; 
     } 
    } 
} 

function doSomethingToObject(thing) 
{ 
    // etc. 
} 
+0

Ngày xửa ngày xưa khi tôi bắt đầu lập trình, tôi đã có một câu lệnh if lồng nhau để kiểm tra mật khẩu thật sự thú vị .... :) – starcorn

0

Sử dụng một

Object object; 
int index = 0; 

do 
{ 
    object = objectList[index]; 
    index++; 
} 
while (object.test == false) 

nếu vi phạm từ một vòng lặp for khiến bạn cảm thấy không thoải mái.

+0

Giả định một chỉ số dạng số. – ChronoFish

+0

Mở rộng ý tưởng cho bất kỳ loại chỉ mục nào miễn là nó có thể được liệt kê và có một cách để chuyển từ mục này sang mục khác. – luvieere

4

Hãy xem, điểm ngắt không gây lỗi cho tôi ở tất cả. Lập trình được được tạo thành trên goto và cho-break - giống như tất cả các cấu trúc điều khiển - chỉ đơn thuần là một hình thức đặc biệt của goto nhằm cải thiện khả năng đọc mã của bạn. Đừng bao giờ cảm thấy xấu về việc viết mã có thể đọc được!

Bây giờ, tôi làm cảm thấy bẩn về so sánh trực tiếp để true, đặc biệt khi sử dụng các nhà điều hành bình đẳng kiểu chuyển đổi ... Oh yeah. Nội dung bạn đã viết - if (object.test == true) - tương đương với văn bản if (object.test), nhưng yêu cầu nhiều suy nghĩ hơn. Nếu bạn thực sự muốn so sánh đó chỉ thành công nếu object.test là cả giá trị boolean true, thì bạn sẽ sử dụng the strict equality operator (===) ... Nếu không, hãy bỏ qua.

+2

Điểm tốt về điều "== đúng". Tôi luôn luôn muốn đề nghị mọi người sử dụng "if ((object.test == true) == true)", chỉ để xem liệu họ có vô lý hay không. –

1

Nói chung không có gì sai với câu lệnh break. Tuy nhiên, mã của bạn có thể trở thành một vấn đề nếu các khối như thế này xuất hiện ở những nơi khác nhau của cơ sở mã của bạn. Trong trường hợp này, các câu lệnh break là mã nhỏ cho mã trùng lặp.

Bạn có thể dễ dàng trích xuất các tìm kiếm vào một chức năng tái sử dụng:

function findFirst(objectList, test) 
{ 
    for (var key in objectList) { 
    var value = objectList[key]; 
    if (test(value)) return value; 
    } 
    return null; 
} 

var first = findFirst(objectList, function(object) { 
    return object.test == true; 
} 
if (first) { 
    //do some process on object 
} 

Nếu bạn luôn xử lý các yếu tố được tìm thấy trong một cách nào đó bạn có thể đơn giản hóa mã của bạn hơn nữa:

function processFirstMatch(objectList, test, processor) { 
    var first = findFirst(objectList, test); 
    if (first) processor(first); 
} 

processFirst(
    objectList, 
    function(object) { 
    return object.test == true; 
    }, 
    function(object) { 
    //do some process on object 
    } 
} 

Vì vậy, bạn có thể sử dụng sức mạnh của các tính năng chức năng trong JavaScript để làm cho mã ban đầu của bạn trở nên biểu cảm hơn. Như một tác dụng phụ, điều này sẽ đẩy câu lệnh break ra khỏi cơ sở mã thông thường của bạn thành một hàm trợ giúp.