Почему при использовании фильтра array_filter (php) выводятся только отфильтрованные параметры, а не элементы массива целиком?

Рейтинг: 0Ответов: 1Опубликовано: 09.03.2023

Есть массив товаров, который фильтрую по диапазону цены $minPrice = 1000; $maxPrice = 4000;

$json_array = [
"0" => [
            'racquetId' => 3457,
            'country' => 'USA',
            'product' => 'Wilson',
            'price' => 990,
            'currency' => 'EUR',
        ],

    "1" => [
            'racquetId' => 5678,
            'country' => 'France',
            'product' => 'Babolat',
            'price' => 2310,
            'currency' => 'EUR'
        ],

    "2" => [
            'racquetId' => 1368,
            'country' => 'France',
            'product' => 'Babolat',
            'price' => 4703,
            'currency' => 'EUR',
        ],

    "3" => [
            'racquetId' => 4568,
            'country' => 'Austria',
            'product' => 'Head',
            'price' => 1480,
            'currency' => 'EUR',
            'startPrice' => 1850,
        ]
];

Почему в случае использования рекурсии, выводится отфильтрованный массив целиком

function recurse_arr($arr,&$filtered_arr2,$minPrice,$maxPrice){
foreach($arr as $key=>$value) {    
    if(isset($value["price"])) {
        if($value["price"] >= $minPrice && $value["price"] <= $maxPrice) {
            $filtered_arr2[$key] = $value;
        }  
    }
   
    //If there's an array within array then recall the function.
    elseif(gettype($value) == 'array') {
        recurse_arr($value,$filtered_arr2);
    }
 
}
 
return $filtered_arr2;
}
 
$filtered_arr2 = [];
print_r(recurse_arr($json_array,$filtered_arr2,$minPrice,$maxPrice));

А при использовании array_filter

$filtered_arr2 = [];
print_r(recurse_arr($json_array,$filtered_arr2,$minPrice,$maxPrice));

$filtered_arr = [];
foreach($json_array as $array=>$racquet) {
    
    array_push($filtered_arr,array_filter($racquet,function($v,$k) use($minPrice,$maxPrice){
        return $k == 'price' && $v >= $minPrice && $v <= $maxPrice;
        
    },ARRAY_FILTER_USE_BOTH));
    
}
//print_r(array_merge(...$filtered_arr));  //Array ([price] => 1480)
print_r($filtered_arr);

Вот в таком виде:

(
    [0] => Array
        (
        )

    [1] => Array
        (
            [price] => 2310
        )

    [2] => Array
        (
        )

    [3] => Array
        (
            [price] => 1480
        )
)

Код целиком и его работа продемонстрирована в песочнице

Ответы

▲ 1Принят

Правильно будет написать так:

$filtered_arr = array_filter(
    $json_array,
    function ($v) use ($minPrice,$maxPrice) {   
        return $v['price'] >= $minPrice && $v['price'] <= $maxPrice; 
    }
);

А с учетом стрелочных функций, доступных начиная с версии 7.4:

$filtered_arr = array_filter(
    $json_array,
    fn ($v) => $v['price'] >= $minPrice && $v['price'] <= $maxPrice
);