如何从平面数组构建树结构

时间:2019-10-17 08:18:27

标签: php arrays tree

我有一系列菜单项:

Array
(
    [0] => Joomla\CMS\Menu\MenuItem Object
        (
            [id] => 101
            [menutype] => mainmenu
            [title] => Home
            [alias] => home
            [note] => 
            [route] => home
            [link] => index.php?option=com_content&view=article&id=9
            [type] => component
            [level] => 1
            [language] => *
            [browserNav] => 0
            [access] => 1
            [home] => 1
            [img] =>  
            [template_style_id] => 0
            [component_id] => 22
            [parent_id] => 1
            [component] => com_content
            [tree] => Array
                (
                    [0] => 101
                )

            [query] => Array
                (
                    [option] => com_content
                    [view] => article
                    [id] => 9
                )

        )

    [1] => Joomla\CMS\Menu\MenuItem Object
        (
            [id] => 118
            [menutype] => mainmenu
            [title] => Legion Bohaterów
            [alias] => legion
            [note] => 
            [route] => legion
            [link] => index.php?Itemid=
            [type] => alias
            [level] => 1
            [language] => *
            [browserNav] => 0
            [access] => 1
            [home] => 0
            [img] =>  
            [template_style_id] => 0
            [component_id] => 0
            [parent_id] => 1
            [component] => 
            [tree] => Array
                (
                    [0] => 118
                )

            [query] => Array
                (
                    [Itemid] => 
                )

        )

    [2] => Joomla\CMS\Menu\MenuItem Object
        (
            [id] => 624
            [menutype] => mainmenu
            [title] => Dołącz do nas
            [alias] => dolacz-do-klubu
            [note] => 
            [route] => legion/dolacz-do-klubu
            [link] => index.php?option=com_content&view=category&layout=blog&id=10
            [type] => component
            [level] => 2
            [language] => *
            [browserNav] => 0
            [access] => 1
            [home] => 0
            [img] =>  
            [template_style_id] => 0
            [component_id] => 22
            [parent_id] => 118
            [component] => com_content
            [tree] => Array
                (
                    [0] => 118
                    [1] => 624
                )

            [query] => Array
                (
                    [option] => com_content
                    [view] => category
                    [layout] => blog
                    [id] => 10
                )

        )

    [3] => Joomla\CMS\Menu\MenuItem Object
        (
            [id] => 599
            [menutype] => mainmenu
            [title] => Wybierz upominki
            [alias] => wybierz-upominki
            [note] => 
            [route] => legion/dolacz-do-klubu/wybierz-upominki
            [link] => index.php?option=com_leg&view=upominki
            [type] => component
            [level] => 3
            [language] => *
            [browserNav] => 0
            [access] => 1
            [home] => 0
            [img] =>  
            [template_style_id] => 0
            [component_id] => 10069
            [parent_id] => 624
            [component] => com_leg
            [tree] => Array
                (
                    [0] => 118
                    [1] => 624
                    [2] => 599
                )

            [query] => Array
                (
                    [option] => com_leg
                    [view] => upominki
                )

        )

在tree元素中,我们有element的父元素(应该在其中附加element)。我做了foreach函数,看起来像这样:

    $mtree = array(); //new stdClass();
    foreach ($menuitems AS $i => $m)
        {
        if (sizeof($m->tree)==1) $mtree[$m->tree[0]]=(array)$m;
        elseif (sizeof($m->tree)==2) $mtree[$m->tree[0]]["c"][$m->tree[1]] = (array)$m;
        elseif (sizeof($m->tree)==3) $mtree[$m->tree[0]]["c"][$m->tree[1]]["c"][$m->tree[2]] = (array)$m;
        elseif (sizeof($m->tree)==4) $mtree[$m->tree[0]]["c"][$m->tree[1]]["c"][$m->tree[2]]["c"][$m->tree[3]] = (array)$m;
        elseif (sizeof($m->tree)==5) $mtree[$m->tree[0]]["c"][$m->tree[1]]["c"][$m->tree[2]]["c"][$m->tree[3]]["c"][$m->tree[4]] = (array)$m;
        }

但这仅适用于特定数量的子树,并且不美观。任何想法如何做到这一点递归? (如何将孩子附加到父母数组中指定的分支上。)

1 个答案:

答案 0 :(得分:0)

以下功能可用于打印显示所有树项及其本身(父项)的树。

function getWithIdsAsKeys($menuItems) {
    $valuesByKey = [];

    foreach ($menuItems as $menuItem) {
        $valuesByKey[$menuItem->id] = $menuItem;
    }

    return $valuesByKey;
};

function printTree($allMenuItems, $menuItems, $depth = 0)
{
    foreach ($menuItems as $menuItem) {
        $prefix = str_repeat('        ', max(0, $depth - 1));
        $nestedSymbol = $depth === 0 ? '' :  '└─';
        echo $prefix . $nestedSymbol . $menuItem->id . '<br />';

        $subTree = array_map(function ($id) use ($allMenuItems, $menuItems) {
            return $allMenuItems[$id];
        }, array_filter($menuItem->tree, function ($id) use ($menuItem) {
            return $id !== $menuItem->id;
        }));

        printTree($allMenuItems, $subTree, $depth + 1);
    }
}
printTree(getWithIdsAsKeys($menuItems), getWithIdsAsKeys($menuItems));

结果:

22
23
└─22
43
└─23
   └─22
44
└─43
   └─23
      └─22