Search code examples
phprecursionmultidimensional-arraykeysanitization

Remove all elements with a specified key while recursively traversing a multidimensional array


Say, I have an array with this structure:

Array
(
    [0] => Array
        (
            [0] => data
            [1] => data
            [2] => data
            [3] => Array
                (
                    [0] => data
                    [thatbastard] => Array
                        (
                            [0] => Array
                                (
                                    [0] => data
                                    [1] => data
                                    [2] => data
                                    [3] => data
                                )

                            [1] => Array
                                (
                                    [0] => data
                                    [1] => data
                                    [2] => data
                                    [3] => data
                                )

                            [2] => Array
                                (
                                    [0] => data
                                    [1] => data
                                    [2] => data
                                    [3] => data
                                )
                        )

                    [2] => data
                )

            [4] => Array
                (
                    [0] => data
                    [thatbastard] => Array
                        (
                            [0] => Array
                                (
                                    [0] => data
                                    [1] => data
                                    [2] => data
                                    [3] => data
                                )

                            [1] => Array
                                (
                                    [0] => data
                                    [1] => data
                                    [2] => data
                                    [3] => data
                                )

                            [2] => Array
                                (
                                    [0] => data
                                    [1] => data
                                    [2] => data
                                    [3] => data
                                )
                        )

                    [2] => data
                )
        )

    [1] => Array(similar to [0])
)

I want to get rid of [thatbastard] all over the array, so my array will look like this:

Array
(
    [0] => Array
        (
            [0] => data
            [1] => data
            [2] => data
            [3] => Array
                (
                    [0] => data
                    [2] => data
                )

            [4] => Array
                (
                    [0] => data
                    [2] => data
                )
        )

    [1] => Array(similar to [0])
)

I've searched widely for hints, but most of them use key_by_value search. In my case I don't care about value, I want to get rid of data by specific key.

I've tried solution based on this topic with recursive function:

 public function filterList($arr, $remove_key)
    {
        foreach ($arr as $key => $value)
        {
            if (is_array($value)) {
                $filtered[$key] = $this->filterList($value, $remove_key);
            }
            else
            {
                if ($key != $remove_key)
                {
                    $filtered[$key] = $value;
                }
            }
        }
        return $filtered;
    }

but it gives the same output as original array.
I've tried this solution, but apparently my array has too many depth levels, and I can't figure out how to improve code.
The problem is I want to write some multitask function that can work with different arrays, not only example.


Solution

  • You can use the array_filter_recursive function from the PHP array_filter documentation. That will work for any multi-dimensional arrays.

    <?php
    
    
    $sweet = array('a' => 'Apple', 'b' => 'Banana');
    $fruits = array('sweet' => $sweet, 'sour' => 'Lemon');
    
    function array_filter_recursive($input, $callback = null) 
    { 
      foreach ($input as &$value) 
      { 
        if (is_array($value)) 
        { 
          $value = array_filter_recursive($value, $callback); 
        } 
      }
      return array_filter($input, $callback, ARRAY_FILTER_USE_BOTH); 
    } 
    
    
    $result = array_filter_recursive($fruits, function ($value, $key) {
      return ($key != 'b');
    });
    
    var_dump($result);