Перерыв array_walk из анонимной функции
Есть ли способ остановить 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. Это возможно.
Ответы
Ответ 1
Как было сказано, теоретически это возможно, но я бы посоветовал это сделать. Здесь, как использовать 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)
*/
Ответ 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';
Но на самом деле это не будет большой разницей, если бы не было "перерыва" вообще. Для каждого недопустимого значения будет назначаться только "ложь", что не имеет значения, поскольку результат будет по-прежнему ложным. Возможно, было бы еще более эффективным, чтобы моя статическая переменная читала.
Лично в вашем случае я бы использовал вместо array_filter
:
$valid = count(array_filter($parent, 'is_numeric')) == count($parent);
или просто
$valid = array_filter($parent, 'is_numeric')) == $parent;
Если все значения в массиве $parent
являются числовыми, все они будут присутствовать после фильтрации. С другой стороны, любое нечисловое значение в массиве повлияет на содержимое (уменьшение количества элементов) в фильтрованном массиве, и сравнение даст ложь.