Существует ли PHP-эквивалент функции JavaScript Array.prototype.some()

В JavaScript мы можем сделать:

function isBiggerThan10(element, index, array) {
  return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some

Существует ли PHP-эквивалент функции some()?

Ответ 1

Нет, в стандартной библиотеке PHP нет короткого замыкания. Существует любое количество решений без короткого замыкания, среди которых array_reduce, вероятно, будет лучше всего соответствовать:

var_dump(array_reduce([2, 5, 8, 1, 4], function ($isBigger, $num) {
    return $isBigger || $num > 10;
}));

Возможно, стоит реализовать собственные функции some/any/all или использовать библиотеку, которая предоставляет набор примитивов функционального программирования, подобных этому, например. https://github.com/lstrojny/functional-php.

Ответ 2

Это не входит, но они легко создаются. Это использует SRFI-1 имена any и every, но могут быть переименованы some и all:

function array_any(array $array, callable $fn) {
    foreach ($array as $value) {
        if($fn($value)) {
            return true;
        }
    }
    return false;
}

function array_every(array $array, callable $fn) {
    foreach ($array as $value) {
        if(!$fn($value)) {
            return false;
        }
    }
    return true;
}

Ответ 3

Здесь array_filter(), который возвращает подмножество данного массива на основе возвращаемого значения данного обратного вызова. Если подмножество пуст, то это будет эквивалент Some(), возвращающий false, и если он не пуст, это будет соответствовать Some(), возвращающему true.

$unfiltered = [1, 11, 2, 22, 3, 33, 4, 44, 5, 55];
$filtered = array_filter ($unfiltered, function ($elem){
    return $elem > 10;
});

print_r ($unfiltered);
print_r ($filtered);
var_dump (empty ($filtered));

Однако этот подход не является короткозамкнутым, и производительность будет обратно пропорциональна размеру массива. Однако это не должно иметь значения в реальном мире, потому что массив все равно должен стать довольно огромным, или array_filter вызывается много раз, прежде чем вы заметите влияние на производительность.

Если производительность имеет первостепенное значение, вам нужно будет самостоятельно скомпилировать массив и выйти из цикла, как только найдете совпадение.

$biggerThanTen = false;
foreach ($unfiltered as $elem)
{
    if ($elem > 10)
    {
        $biggerThanTen = true;
        break;
    }
}

Ответ 4

Использовать array_filter и обеспечить обратный вызов. Оберните это в другую функцию, чтобы подсчитать, есть ли какие-либо результаты

function array_some(array $data, callable $callback) {
    $result = array_filter($data, $callback);
    return count($result) > 0;
}

$myarray = [2, 5, 8, 12, 4];
array_some($myarray, function($value) {
    return $value > 10;
}); // true