2013-07-25 22 views
15

Có cách nào để dừng một số array_walk từ bên trong chức năng ẩn danh không?Break array_walk từ hàm ẩn danh

Dưới đây là một số mã mẫu (hoạt động) để hiển thị ý của tôi, kiểm tra xem một mảng có chỉ giá trị số không.

$valid = true; 
array_walk($parent, function ($value) use (&$valid) { 
    if (!is_numeric($value)) { 
     $valid = false; 
    } 
}); 

return $valid ? 'Valid' : 'Invalid'; 

Nếu tôi có một mảng đủ lớn và mục nhập đầu tiên không hợp lệ, phần còn lại của các kiểm tra (dự phòng) vẫn được thực hiện, vì vậy tôi muốn ngừng thực hiện.

Sử dụng break/continue không hoạt động (lỗi: Fatal error: Cannot break/continue 1 level in ...).

Lưu ý: Tôi không muốn viết lại mã, tôi chỉ muốn biết NẾU điều này là có thể.

+3

Bạn * có thể * ném, sau đó bắt, một Ngoại lệ. Tất nhiên, đó là cách tiếp cận sai, nhưng có thể. –

+0

Không thể trực tiếp, nhưng chính xác bạn vẽ đường để viết lại mã ở đâu? (Giải pháp 'Exception' có vẻ như nó hoạt động, nhưng tôi sẽ sớm sử dụng một' foreach' đơn giản hơn là làm điều đó). – Jon

+0

@Jon: Vâng, tôi đã tò mò nếu có thể cho các chức năng như thế này. Tôi không muốn sử dụng 'for' /' foreach', đó là nó (chủ yếu là một câu hỏi lý thuyết :)). Anthony, bạn nên đăng nó như một câu trả lời. –

Trả lời

11

Như đã nêu, về mặt lý thuyết có thể nhưng tôi khuyên bạn nên chống lại nó. Dưới đây là cách sử dụng Ngoại lệ để thoát ra khỏi số array_walk.

<?php 
$isValid = false; 

$array = range(1, 5); 

try { 
    array_walk($array, function($value) { 
     $isAMagicNumber = 3 === $value; 
     if ($isAMagicNumber) { 
      throw new Exception; 
     } 
    }); 
}catch(Exception $exception) { 
    $isValid = true; 
} 

var_dump($isValid); 

/* 
    bool(true) 
*/ 
+0

Điều này có thể hữu ích nếu đây là kiểm tra chính trong ứng dụng của bạn, và bạn vẫn sẽ ném ngoại lệ. Làm một cái gì đó như 'ném mới InvalidInputException;', sau đó xử lý nó đúng cách. Nhưng trong hầu hết các trường hợp, tốt hơn là không nên làm điều này :) Cảm ơn bạn đã trả lời! –

6

Bạn có thể đặt một lá cờ tĩnh bên trong hàm ẩn danh:

array_walk($ary, function($item) { 
    static $done = false; 
    if($done) { 
     return; 
    } 

    // … your code 

    if($myBreakCondition) { 
     $done = true; 
     return; 
    } 
}); 

này không thực sự ngăn chặn sự lặp đi lặp lại, nhưng tất cả các chu kỳ tiếp tục sau khi lá cờ được thiết lập chỉ đơn giản là không làm gì cả. Không phải là rất hiệu quả, nhưng nó có thể làm việc mà không có bất kỳ tác động hiệu suất lớn hơn nếu các mảng được lặp lại không quá lớn.

Trong trường hợp của bạn, mã sẽ là:

$valid = true; 
array_walk($parent, function($value) use(&$valid) { 
    static $done = false; 
    if($done) { 
     return; 
    } 

    if(!is_numeric($value)) { 
     $valid = false; 
     $done = true; 
     return; 
    } 
}); 
return $valid ? 'Valid' : 'Invalid'; 

Nhưng trên thực tế nó sẽ không có nhiều khác biệt nếu không có “đột phá” ở tất cả. Chỉ có “sai” sẽ được gán cho mọi giá trị không hợp lệ, điều này không quan trọng vì kết quả sẽ vẫn là sai. Có lẽ nó sẽ hiệu quả hơn nếu biến tĩnh của tôi bị lừa.

Cá nhân trong trường hợp của bạn tôi sẽ sử dụng array_filter thay vì:

$valid = count(array_filter($parent, 'is_numeric')) == count($parent); 

hoặc chỉ

$valid = array_filter($parent, 'is_numeric')) == $parent; 

Nếu tất cả các giá trị trong mảng $parent là số, họ sẽ là tất cả hiện tại sau khi lọc. Mặt khác, bất kỳ giá trị không phải số nào trong mảng sẽ ảnh hưởng đến nội dung (giảm số lượng mục) trong mảng được lọc và so sánh sẽ mang lại giá trị sai.

Các vấn đề liên quan