3

I am trying to filter a multi-dimension array by removing subarrays where the permission value is no.

My array:

$array = array(
    array(
        'name' => 'dashboard',
        'permission' => 'yes'
    ),
    array(
        'name' => 'Purchase Orders',
        'permission' => 'yes',
        'dropdown' => array(
            array(
                'name' => 'View Complete',
                'permission' => 'yes'
            ),
            array(
                'name' => 'New PO',
                'permission' => 'no'
            )
        )
    ),
    array(
        'name' => 'dashboard',
        'permission' => 'no'
    )
);

This is my desired result: (notice all groups with permission=>'no' have been fully removed)

$array = array(
    array(
        'name' => 'dashboard',
        'permission' => 'yes'
    ),
    array(
        'name' => 'Purchase Orders',
        'permission' => 'yes',
        'dropdown' => array(
            array(
                'name' => 'View Complete',
                'permission' => 'yes'
            )
        )
    )
);

Using array_filter() with a callback function does this very simply on the first level, but I cannot work out a simple solution for doing it on every level.

At the moment my solution is looping and unsetting each key, but it needs to know the exact structure of the array and feels quite messy.

2
  • Is it always up to 2 levels deep? Commented Dec 12, 2017 at 0:00
  • 2
    You could recurse and check if an element is an array with is_array and check permission value. That way you don't have to know how deep the structure is. Commented Dec 12, 2017 at 0:06

2 Answers 2

1

Here is a method with recursion. A few inline comments to help explain, but there isn't much to explain that the basic functions don't express inherently.

Code: (Demo)

$array = array(
array(
    'name' => 'dashboard',
    'permission' => 'yes'
),
array(
    'name' => 'Purchase Orders',
    'permission' => 'yes',
    'dropdown' => array(
        array(
            'name' => 'View Complete',
            'permission' => 'yes'
        ),
        array(
            'name' => 'New PO',
            'permission' => 'no'
        )
    )
),
array(
    'name' => 'dashboard',
    'permission' => 'no'
));

function recursive_filter($array){
    foreach($array as $k=>&$subarray){  // make modifiable by reference
        if(isset($subarray['permission']) && $subarray['permission']=='no'){ // check that this element exists before trying to access it
            unset($array[$k]);  // remove subarray
        }elseif(isset($subarray['dropdown'])){  // check that this element exists before trying to access it
            $subarray['dropdown']=recursive_filter($subarray['dropdown']);  // recurse
        }
    }
    return $array;
}

var_export(recursive_filter($array));

Output:

array (
  0 => 
  array (
    'name' => 'dashboard',
    'permission' => 'yes',
  ),
  1 => 
  array (
    'name' => 'Purchase Orders',
    'permission' => 'yes',
    'dropdown' => 
    array (
      0 => 
      array (
        'name' => 'View Complete',
        'permission' => 'yes',
      ),
    ),
  ),
)
Sign up to request clarification or add additional context in comments.

Comments

1

Little bit complicated. This works only if the array is not getting deeper than the example you gave.

foreach($array as $key => $item) {
    if(isset($item['permission']) && $item['permission'] == 'no') {
        unset($array[$key]);
    }
    if(isset($item['dropdown'])) {
       foreach($item['dropdown'] as $key2 => $item2) {
            if(isset($item2['permission']) && $item2['permission'] == 'no') {
                unset($array[$key]['dropdown'][$key2]);
            }
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.