从匿名函数中断array_walk

时间:2013-07-25 08:42:57

标签: php anonymous-function

有没有办法在匿名函数内停止array_walk

下面是一些示例代码(可行),用于显示我的意思,检查数组是否只有数值。

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

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

如果我有一个足够大的数组,并且第一个条目无效,其余的(冗余)检查仍然完成,所以我想停止执行。

使用break / continue不起作用(错误:Fatal error: Cannot break/continue 1 level in ...)。

注意:我不想重写代码,我只想知道 IF 这是可能的。

2 个答案:

答案 0 :(得分:14)

如上所述,从理论上说这是可能的,但我建议反对它。以下是如何使用Exception来突破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)
*/

答案 1 :(得分:7)

您可以在匿名函数中放置一个静态标志:

function time_spended($time){
    switch($time){
        case ($time > (60*60*24*365)):
            $time /= (60*60*24*365);
            return number_format($time, 2, '.', ',') . " year" . ($time > 1 ? "s":"");
            break;
        case ($time > 60*60*24):
            $time /= 60*60*24;
            return number_format($time, 2, '.', ',') . " day" . ($time > 1 ? "s":"");
            break;
        case ($time > 60*60):
            $time /= 60*60;
            return number_format($time, 2, '.', ',') . " hour" . ($time > 1 ? "s":"");
            break;
        case ($time > 60):
            $time /= 60;
            return number_format($time, 2, '.', ',') . " minute" . ($time > 1 ? "s":"");
            break;
        default:
            return number_format($time, 2, '.', ',') . " seconds";
    }
}

这实际上并没有停止迭代,但是设置标志后的所有进一步循环都不做任何事情。效率不高,但如果迭代的数组不是太大,它可能会在没有任何更大性能影响的情况下工作。

在您的情况下,代码将是:

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

    // … your code

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

但实际上,如果根本没有“休息”,那将没有多大区别。只为每个无效值分配“假”,这无关紧要,因为结果仍然是假的。也许我的静态变量欺骗会更有效率。

就你个人而言,我会改为使用$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';

array_filter

或只是

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

如果$valid = array_filter($parent, 'is_numeric')) == $parent; 数组中的所有值都是数字,则过滤后它们将全部存在。另一方面,数组中的任何非数字值都会影响已过滤数组中的内容(减少项目数),并且比较将产生错误。