Перебрать многомерный массив и удалить определенные ключи - PullRequest
2 голосов
/ 10 апреля 2010

У меня есть вложенная древовидная структура, основанная на массиве ниже:

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

Его можно использовать для удаления ключа в любом месте массива, но только на основе одной вещи, например, удалить все ключи, где «родительский» равен «23». Но мне нужно найти и удалить (сбросить) все ключи, где «basename» равно нулю И где child не является массивом или где массив пуст. Кто-нибудь может мне помочь и, возможно, настроить вышеописанную функцию?

Спасибо,

Ответы [ 2 ]

1 голос
/ 10 апреля 2010

Решено! Добавил эту функцию в мой класс:

private function cleanTree(&$arr){
    foreach($arr as $key => &$item) {
        if(!$item["child"] && empty($item["basename"])){
            unset($arr[$key]);</p>

<pre><code>    }elseif(is_array($item["child"])){
        if(count($item["child"]) == 0){
            unset($arr[$item["id"]]);
        }else{
            $this->cleanTree($item["child"]);
        }
    }
}
</code>

}

Чтобы удалить ненужные элементы на уровне (ах) ROOT, а также кого-либо еще, просто запустите вышеуказанное дважды.

1 голос
/ 10 апреля 2010

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

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 (или если вы вызываете <code>searchAndDestroy с этой функцией более чем в одном месте), назовите функцию и передайте имя, а не анонимную функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...