views:

298

answers:

4

Hi!

I've got a nested tree structure which is based on the array below:

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 (recursive?) through the array and remove some keys.

I my system I can allow users to certain functions/pages and if I deny access to the whole "block" "Events", the array will look 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 whole "block" "Events" is useless right now, becuase 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 remove them. I found this function when 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 remove a key any where in the array, but only based in one thing, for example remove all keys where "parent" equals "23". But I need to find and remove (unset) all keys where "basename" is null AND where child isn't an array or where the array is empty. Can anyone help me out and possibly tweak the function above?

Thank you,

A: 

Rather than putting the test for which elements to destroy in the search function, pass a function to test for 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 that function in more than one spot), name the function and pass the name rather than an anonymous function.

outis
A: 
Webkungen
outis
As for the error, read the last line of my post: "For PHP < 5.3 (or if you call searchAndDestroy with that function in more than one spot), name the function and pass the name rather than an anonymous function."
outis
If you haven't yet, read the FAQs (start with the link at the top of the page) and formatting help (click the orange question mark in the post text editing toolbar).
outis
This is PHP, not Javascript. Unless you're running PHP 5.3, you can't use lambda functions (`function($k, $v) {...}`) in your code. Don't know what you're doing there, but it's not allowed.
mattbasta
@mattbasta: I've already addressed that point twice.
outis
A: 

Here's the same structure returned by "var_export" instead of "print_r" as requested:

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' => '',
      ),
    ),
  )
)

Webkungen
+1  A: 
Webkungen
What if useless items go down 3 levels?
outis