从匿名函数中分离array_walk

2022-08-30 21:09:34

有没有办法从匿名函数内部阻止array_walk

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

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

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

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

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

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


答案 1

如前所述,从理论上讲这是可能的,但我建议不要这样做。下面介绍如何使用异常来突破 .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)
*/

答案 2

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

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';

但实际上,如果根本没有“中断”,也不会有太大的区别。只有“false”将为每个无效值分配,这无关紧要,因为结果仍然是假的。也许它会比我的静态变量作弊更有效。

就个人而言,在你的情况下,我会改用:array_filter

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

或者只是

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

如果数组中的所有值都是数字,则在筛选后它们都将存在。另一方面,数组中的任何非数值都会影响筛选数组中的内容(减少项目计数),并且比较将产生 false。$parent


推荐