Search code examples
phparraysmultidimensional-arrayfilter

PHP recursive loop to filter out item and subitem based on key, value condition


I'm facing a multi dimenstions array filter problem. Let's say I had more than 3, or 50 levels of arrays inside an array, how can we filter them based on a key, value pair?

for Example:

$arr = [
        [ 'key' => 1, 'canView' => false, 'child' => [
            ['key'=> 10, 'canView' => true]
        ],
        ['key' => 2, 'canView' => false],
        ['key' => 3, 'canView' => true, 'child' => [
            ['key'=> 10, 'canView' => true, 'child' => [
            ['key'=> 10, 'canView' => true]] //and so on...
           ],...
        ],
        ['key' => 4, 'canView' => false],
        ['key' => 5, 'canView' => false],
        ];

and then, using filterArray($array, $key, $condition) to filter out those child elements and items that have the 'canView' => false.

Expected result from the Example above: key 10: removed because its parent key 1 had the 'canView' => false and all the other 'canView'=>false will be removed as well, only keep those that it and its parent (if any) both had the 'canView' => true attribute.

I've tried this code, but it only filter the 1st level array.

function filterArray($array, $key, $value)
      {
          foreach ($array as $subKey => $subArray) {
              if ($subArray[$key] == $value) {
                  unset($array[$subKey]);
              }
          }
          return $array;
      }

How can we turn it into a recursive loop that auto-detects if there's another child array present?


Solution

  • To recursively work into an array, you can call your own function recursively on the "child" keys.

    function filterArray($array, $key, $value){
        foreach ($array as $subKey => $subArray) {
            if ($subArray[$key] == $value) {
                unset($array[$subKey]);
            } elseif (!empty($subArray['child']) && is_array($subArray['child'])) {
                $array[$subKey]['child'] = filterArray($subArray['child'], $key, $value);
            }
        }
        return $array;
    }