Loop through a multidimensional array and remove specific keys
I have a nested tree structure based on the following array:
Array
(
[1] => Array
(
[id] => 1
[parent] => 0
[name] => Startpage
[uri] => 125
[basename] => index.php
[child] =>
)
[23] => Array
(
[id] => 23
[parent] => 0
[name] => Events
[uri] => 0
[basename] =>
[child] => Array
(
[24] => Array
(
[id] => 24
[parent] => 23
[name] => Public news
[uri] => 0
[basename] =>
[child] => Array
(
[27] => Array
(
[id] => 27
[parent] => 24
[name] => Add
[uri] => 100
[basename] => news.public.add.php
[child] =>
)
[28] => Array
(
[id] => 28
[parent] => 24
[name] => Overview
[uri] => 101
[basename] => news.public.overview.php
[child] =>
)
)
)
[25] => Array
(
[id] => 25
[parent] => 23
[name] => Private news
[uri] => 0
[basename] =>
[child] => Array
(
[29] => Array
(
[id] => 29
[parent] => 25
[name] => Add
[uri] => 67
[basename] => news.private.add.php
[child] =>
)
[30] => Array
(
[id] => 30
[parent] => 25
[name] => Overview
[uri] => 68
[basename] => news.private.overview.php
[child] =>
)
)
)
[26] => Array
(
[id] => 26
[parent] => 23
[name] => Calendar
[uri] => 0
[basename] =>
[child] => Array
(
[31] => Array
(
[id] => 31
[parent] => 26
[name] => Add
[uri] => 69
[basename] => news.event.add.php
[child] =>
)
[32] => Array
(
[id] => 32
[parent] => 26
[name] => Overview
[uri] => 70
[basename] => news.event.overview.php
[child] =>
)
)
)
)
)
)
I'm looking for a function to loop (recursively?) Through an array and remove some keys.
On my system, I can allow users to certain functions / pages, and if I deny access to the whole "Events" "block", the array looks like this:
array (
1 =>
array (
'id' => '1',
'parent' => '0',
'name' => 'Start page',
'uri' => '125',
'basename' => 'index.php',
'child' => '',
),
23 =>
array (
'id' => '23',
'parent' => '0',
'name' => 'Events',
'uri' => '0',
'basename' => NULL,
'child' =>
array (
24 =>
array (
'id' => '24',
'parent' => '23',
'name' => 'Public news',
'uri' => '0',
'basename' => NULL,
'child' => '',
),
25 =>
array (
'id' => '25',
'parent' => '23',
'name' => 'Private news',
'uri' => '0',
'basename' => NULL,
'child' => '',
),
26 =>
array (
'id' => '26',
'parent' => '23',
'name' => 'Calendar',
'uri' => '0',
'basename' => NULL,
'child' => '',
),
),
)
)
As you can see above, the entire Events "block" is useless right now because there is no page associated with each option. So I need to find all "keys" where "basename" is null AND where child is not an array or where the array is empty and removes them. I found this function while searching the site:
function searchAndDestroy(&$a, $key, $val){
foreach($a as $k => &$v){
if(is_array($v)){
$r = searchAndDestroy($v, $key, $val);
if($r) {
unset($a[$k]);
}
} elseif ($key == $k && $val == $v) {
return true;
}
}
return false;
}
It can be used to delete a key by anyone where it is in the array, but only based on one thing, for example, it removes all keys where "parent" is "23". But I need to find and remove (delete) all keys where "basename" is N and where child is not an array or where the array is empty. Can anyone help me and maybe tweak the function above?
Thank,
source to share
I decided! Added a function to my class:
private function cleanTree (& $ arr) {
foreach ($ arr as $ key => & $ item) {
if (! $ item ["child"] && empty ($ item ["basename"])) {
unset ($ arr [$ key]);
}elseif(is_array($item["child"])){
if(count($item["child"]) == 0){
unset($arr[$item["id"]]);
}else{
$this->cleanTree($item["child"]);
}
}
}
}
To remove unnecessary items at the ROOT level (s), as well as anyone else, just run the above.
source to share
Instead of putting a test for which items are destroyed in the search function, pass the function to test the targets.
function searchAndDestroy(&$a, $targetp){
foreach($a as $k => &$v){
if(is_array($v)){
searchAndDestroy($v, $targetp);
}
if ($targetp($k, $v)) {
unset($a[$k]);
}
}
}
searchAndDestroy($menu, function ($k, $v) {
return is_array($v)
&& array_key_exists('basename', $v) && empty($v['basename'])
&& (empty($v['child']) || count($v['child']) == 0);
});
For PHP <5.3 (or if you call searchAndDestroy
with this function in more than one place), name the function and pass the name, not the anonymous function.
source to share