Удаление массивов из многомерного массива на основе отдельных значений

Я пытаюсь отфильтровать многомерный массив, удалив подмассивы, где permission значение no,

Мой массив:

$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'
)
);

Это мой желаемый результат: (обратите внимание на все группы с permission=>'no' были полностью удалены)

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

С помощью array_filter() с функцией обратного вызова делает это очень просто на первом уровне, но я не могу найти простое решение для этого на каждом уровне.

На данный момент мое решение зацикливает и сбрасывает все ключи, но оно должно знать точную структуру массива и выглядит довольно грязно.

3

Решение

Вот метод с рекурсией. Несколько встроенных комментариев, чтобы помочь объяснить, но не так много, чтобы объяснить, что основные функции не выражают по своей сути.

Код: (демонстрация)

$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));

Выход:

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

Другие решения

Немного сложно. Это работает, только если массив не становится глубже, чем приведенный вами пример.

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]);
}
}
}
}
1