Вопрос или проблема
В JavaScript мы можем сделать следующее:
function isBiggerThan10(element, index, array) {
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10); // ложь
[12, 5, 8, 1, 4].some(isBiggerThan10); // истина
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
Есть ли аналог функции some() в PHP?
Она не входит в стандартную библиотеку, но их легко создать. Это использует имена 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;
}
Нет, в стандартной библиотеке 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.
Редактировать: PHP >= 8.4
Теперь в PHP 8.4 вы можете использовать array_any
$some = array_any($data, fn ($item) => $item > 10);
Так же, как и ее эквивалент для Array.every()
в PHP 8.4, вы можете использовать array_all
$every = array_all($data, fn ($item) => $item > 10);
https://php.watch/versions/8.4/array_find-array_find_key-array_any-array_all
PHP < 8.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;
}); // истина
Есть array_filter(), который возвращает подмножество данного массива на основе возвращаемого значения данного колбека. Если подмножество пусто, то это будет эквивалентно тому, что Some() возвращает ложь, а если не пусто, то это будет соответствовать тому, что Some() возвращает истину.
$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;
}
}
function array_some(array $array, callable $callback) {
$i = 0;
$n = count($array);
while($i<$n && !$callback($array[$i])) {
$i++;
}
return $array[$i] ?? null;
}
Функция возвращает null, если не найден ни один элемент, удовлетворяющий условию функции “callback”.
Если будет найден элемент, удовлетворяющий условию, она вернет первый найденный.
Функция “callback”, переданная в качестве параметра, должна возвращать true или false в зависимости от того, удовлетворяет ли элемент условию.
Вот функция PHP, которая работает как функция JavaScript Array.some().
Я думаю, что код говорит сам за себя, но если у вас есть какие-либо вопросы, не стесняйтесь спрашивать меня.
// Функция Array.some(), подобная JavaScript
$array_some = function($an_array, $callback_function) {
$is_data_found = false;
foreach ($an_array as $an_array_index => $array_item) {
$is_data_found = $callback_function($array_item, $an_array_index, $an_array);
if ($is_data_found) return $is_data_found;
}
return $is_data_found;
};
Использование в обычном массиве:
$numbers = [12, 34, 27, 23, 65, 93, 36, 87, 4, 254];
$is_any_number_less_than500 = $array_some($numbers, fn($number) => $number < 500) === false ? 'ложь' : 'истина';
echo("<pre>есть ли число < 500: $is_any_number_less_than500</pre><br />");
// есть ли число < 500: истина
$is_any_number_more_than500 = $array_some($numbers, fn($number) => $number > 500) === false ? 'ложь' : 'истина';
echo("<pre>есть ли число > 500: $is_any_number_more_than500</pre><br /><br />");
// есть ли число > 500: ложь
Использование в ассоциативном массиве:
(Массив объектов, подобный JavaScript / JSON, подобный JavaScript)
$products = [
['id' => 'id_1', 'price' => 30],
['id' => 'id_2', 'price' => 233],
['id' => 'id_3', 'price' => 5],
['id' => 'id_4', 'price' => 499]
];
$is_any_product_price_less_than500 = $array_some($products, fn($product) => @$product['price'] < 500) === false ? 'ложь' : 'истина';
echo("<pre>есть ли цена товара < 500: $is_any_product_price_less_than500</pre><br />");
// есть ли цена товара < 500: истина
$is_any_product_price_more_than500 = $array_some($products, fn($product) => @$product['price'] > 500) === false ? 'ложь' : 'истина';
echo("<pre>есть ли цена товара > 500: $is_any_product_price_more_than500</pre><br /><br />");
// есть ли цена товара > 500: истина
Использование данных OP:
$is_any_number_bigger_than10 = $array_some([2, 5, 8, 1, 4], fn($number) => $number > 10) === false ? 'ложь' : 'истина';
echo("<pre>есть ли число > 10: $is_any_number_bigger_than10</pre><br />");
// есть ли число > 10: ложь
$is_any_number_bigger_than10 = $array_some([12, 5, 8, 1, 4], fn($number) => $number > 10) === false ? 'ложь' : 'истина';
echo("<pre>есть ли число > 10: $is_any_number_bigger_than10</pre><br /><br />");
// есть ли число > 10: истина
Ответ или решение
В PHP нет прямого аналога функции Array.prototype.some()
из JavaScript, однако, вы можете легко создать свою собственную функцию, которая будет выполнять ту же задачу.
Функция some()
в JavaScript проверяет, удовлетворяет ли хотя бы один элемент массива условию, заданному в переданной функции-коллбэке, и возвращает true
или false
в зависимости от результата. А вот решения для PHP можно реализовать несколькими способами.
Решение для PHP < 8.4
Если вы используете PHP версии ниже 8.4, вы можете определить следующую функцию array_some()
, чтобы добиться похожего поведения:
function array_some(array $array, callable $callback) {
foreach ($array as $item) {
if ($callback($item)) {
return true; // Если коллбэк возвращает true, возращаем true
}
}
return false; // Если ни один элемент не прошел, возвращаем false
}
// Пример использования
$numbers1 = [2, 5, 8, 1, 4];
$result1 = array_some($numbers1, fn($number) => $number > 10); // false
$numbers2 = [12, 5, 8, 1, 4];
$result2 = array_some($numbers2, fn($number) => $number > 10); // true
var_dump($result1); // bool(false)
var_dump($result2); // bool(true)
Решение для PHP >= 8.4
С выходом версии PHP 8.4 в стандартную библиотеку были добавлены функции array_any()
и array_all()
, которые обеспечивают прямой аналог JavaScript функции some()
:
// Пример использования функции array_any в PHP 8.4 и выше
$data = [2, 5, 8, 1, 4];
$some = array_any($data, fn($item) => $item > 10); // false
$data2 = [12, 5, 8, 1, 4];
$some2 = array_any($data2, fn($item) => $item > 10); // true
var_dump($some); // bool(false)
var_dump($some2); // bool(true)
Использование array_filter
Также можно использовать функцию array_filter
, чтобы отфильтровать элементы массива по условию:
function array_some_via_filter(array $data, callable $callback) {
$filtered = array_filter($data, $callback); // Фильтруем массив
return count($filtered) > 0; // Если имеются элементы, удовлетворяющие условию, возвращаем true
}
$result3 = array_some_via_filter([2, 5, 8, 1, 4], fn($number) => $number > 10); // false
$result4 = array_some_via_filter([12, 5, 8, 1, 4], fn($number) => $number > 10); // true
var_dump($result3); // bool(false)
var_dump($result4); // bool(true)
Заключение
В зависимости от версии вашего PHP и ваших предпочтений, вы можете использовать один из предложенных способов для реализации функциональности, аналогичной Array.prototype.some()
из JavaScript. В PHP 8.4 и выше возможности стандартной библиотеки значительно расширены, что упрощает выполнение таких задач без необходимости писать дополнительные функции.