Search code examples
phparraysrecursionmultidimensional-arrayarray-filter

Recursively filter items in a multidimensional array do not contain array-type data unless having a whitelisted key


I have array the following multidimensional array:

$arr = [
    'test' => [
        'access' => 111,
        'aa' => [
            'access' => 222,
            'bb' => 333
        ],
    ],
    'access' => 444,
    'value' => 555
];

Desired result:

[
  'test' => [
    'access' => 111,
    'aa' => [
      'access' => 222,
    ],
  ],
  'access' => 444,
]

My code:

function array_filter_recursive($input)
{
    foreach ($input as &$value) {
        if (is_array($value)) {
            $value = array_filter_recursive($value);
        }
    }
    return array_filter($input,function ($key){
            return $key == 'access';
        },ARRAY_FILTER_USE_KEY);
}

var_dump(array_filter_recursive($arr));

However, my code only returns 1 item.

If I change the function like return $key != 'access';, it returns the array without key == access but it's not working if $key == 'access'.


Solution

  • You only want to remove a key if it's not named access and the value is not a nested array. This way, you keep any intermediate arrays.

    You can't use array_filter(), because it only receives the values, not the keys. So do it in your foreach loop.

    function array_filter_recursive($input)
    {
        foreach ($input as $key => &$value) {
            if (is_array($value)) {
                $value = array_filter_recursive($value);
                if (empty($value)) {
                    unset($input[$key]);
                }
            } elseif ($key != 'access') {
                unset($input[$key]);
            }
        }
        return $input;
    }