循环遍历多维数组并删除某些键

时间:2010-04-10 10:46:58

标签: php arrays menu nested recursion

我有一个基于下面数组的嵌套树结构:

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] => 
                                        )

                                )

                        )

                )

        )
)

我正在寻找一个通过数组循环(递归?)的函数并删除一些键。

我的系统我可以允许用户使用某些功能/页面,如果我拒绝访问整个“块”“事件”,则数组将如下所示:

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

正如您在上面所看到的,整个“块”“事件”现在没用,因为没有与每个选项相关联的页面。所以我需要找到所有“键”,其中“basename”为空,其中child不是数组或数组为空并删除它们。 我在搜索网站时发现了这个功能:

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;
}

它可用于删除数组中任何位置的键,但仅基于一个,例如删除“parent”等于“23”的所有键。但我需要找到并删除(取消设置)“basename”为空的所有键,其中child不是数组,或者数组为空。 任何人都可以帮助我,并可能调整上述功能吗?

谢谢,

2 个答案:

答案 0 :(得分:1)

不是在搜索函数中测试要销毁哪些元素,而是传递一个函数来测试目标。

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

对于PHP< 5.3(或者如果你在多个地点使用该功能调用searchAndDestroy),请命名该函数并传递名称而不是匿名函数。

答案 1 :(得分:1)

解决了!将此功能添加到我的班级:

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

}

要删除ROOT级别以及其他任何人的不必要元素,只需运行上面两次。