简体   繁体   English

嵌套数组的PHP递归迭代

[英]PHP Recursive Iteration for Nested Array

I have following array, the depth of array cannot be known since array can have n childs. 我有以下数组,因为数组可以有n个孩子,所以无法知道数组的深度。

$menu = [
    [
        'name' => 'home',
        'label' => 'Home',
        'uri' => '/home',
        'order' => 1,
        'attributes' => [
            'class' => ['home-class', 'home-class-2'],
            'id' => ['home-id']
        ]
    ], [
        'name' => 'about',
        'label' => 'About',
        'uri' => '/about',
        'order' => 2,
        'attributes' => [
            'class' => [],
            'id' => []
        ],
        'child' => [
            [
                'name' => 'company_profile',
                'label' => 'Company Profile',
                'uri' => '/company-profile',
                'order' => 1,
                'attributes' => [
                    'class' => [],
                    'id' => []
                ]
            ], [
                'name' => 'team',
                'label' => 'Team',
                'uri' => '/team',
                'order' => 2,
                'attributes' => [
                    'class' => ['team-class', 'team-class-2'],
                    'id' => ['team-id']
                ],
                'child' => [
                    [
                        'name' => 'management_team',
                        'label' => 'Management Team',
                        'uri' => '/management-team',
                        'order' => 1,
                        'attributes' => [
                            'class' => [],
                            'id' => []
                        ]
                    ],
                    [
                        'name' => 'development_team',
                        'label' => 'Development Team',
                        'uri' => '/development-team',
                        'order' => 2,
                        'attributes' => [
                            'class' => [],
                            'id' => []
                        ]
                    ],

                ]
            ],
        ]
    ], [
        'name' => 'services',
        'label' => 'Services',
        'uri' => '/services',
        'order' => 3,
        'attributes' => [
            'class' => [],
            'id' => []
        ],
        'child' => [
            [
                'name' => 'web_application',
                'label' => 'Web Application',
                'uri' => '/web-application',
                'order' => 1,
                'attributes' => [
                    'class' => [],
                    'id' => []
                ]
            ], [
                'name' => 'mobile_application',
                'label' => 'Mobile Application',
                'uri' => '/mobile-application',
                'order' => 2,
                'attributes' => [
                    'class' => [],
                    'id' => []
                ]
            ], [
                'name' => 'cms_development',
                'label' => 'CMS Development',
                'uri' => '/cms-development',
                'order' => 3,
                'attributes' => [
                    'class' => [],
                    'id' => []
                ]
            ],
        ]
    ]
];

I want to loop this over and pass data to object, for example. 例如,我想循环遍历并将数据传递给对象。

$nav = new Navigation\Menu('main');
foreach ($menu as $item) {
    // Parent element
    $navItem = new Navigation\Item($item['name']);
    $navItem->setLabel($item['label']);
    $navItem->setUri($item['uri']);
    $nav->addItem($navItem);
    if (isset($item['child']) && is_array($item['child'])) {
        // First child
        foreach ($item['child'] as $child1) {
            $childItem1 = new Navigation\Item($child1['name']);
            $childItem1->setLabel($child1['label']);
            $childItem1->setUri($child1['uri']);
            $navItem->addChild($childItem1);
            if (isset($child1['child']) && is_array($child1['child'])) {
                // Second child
                foreach ($child1['child'] as $child2) {
                    $childItem2 = new Navigation\Item($child2['name']);
                    $childItem2->setLabel($child2['label']);
                    $childItem2->setUri($child2['uri']);
                    $childItem1->addChild($childItem2);
                }
            }
        }
    }
}

This works but with a problem. 这可行,但是有问题。 As you see, I am manually looping over each child, I do not want this, what i am looking for is, It must iterate the array recursively allowing to add any number of child with any depth. 如您所见,我手动遍历每个孩子,我不想要这个,我要寻找的是,它必须递归地迭代数组,以允许添加任意数量的任何深度的孩子。

I tried array_walk_recursive or custom recursive function without any result. 我尝试了array_walk_recursive或自定义递归函数,但没有任何结果。 any pointer to solve this is appreciated. 任何解决这个问题的指针都值得赞赏。

Thanks. 谢谢。

Here is a little recursive script that should run through every if it is an array or an object, each recursion will return the object. 这是一个小小的递归脚本,无论是数组还是对象,每个脚本都应运行,每次递归都会返回该对象。 Now this would need some editing for your usage. 现在,您需要对其进行一些编辑。 But it should give you a starting point. 但这应该为您提供一个起点。

function Navigation($item) {
    if (is_object($item)) {
        foreach (get_object_vars($item) as $property => $value) {
            //If item is an object, then run recursively
            if (is_array($value) || is_object($value)) {
                $item->$property =  Navigation($item);
            } else {
                $navItem->setLabel($item['label']);
                $navItem->setUri($item['uri']);
                $nav->addItem($navItem);
            }
        }
        return $nav;
    } elseif (is_array($item)) {
        foreach ($item as $property => $value) {
            //If item is an array, then run recursively
            if (is_array($value) || is_object($value)) {
                $item[$property] =  Navigation($item);
            } else {
                $navItem->setLabel($item['label']);
                $navItem->setUri($item['uri']);
                $nav->addItem($navItem);
            }
        }
        return $nav;
    }
    $navItem->setLabel($item['label']);
    $navItem->setUri($item['uri']);
    $nav->addItem($navItem);
}

Figured it out finally. 终于明白了。

Here is how i did it using custom recursive function. 这是我使用自定义递归函数的方法。

function recursive($menu, &$nav, $child = false, $parent = null)
{
    foreach ($menu as $page) {
        $navItem = new Navigation\Item($page['name']);
        if (false == $child) {
            $nav->addItem($navItem);
        } else {
            $parent->addChild($navItem);
        }
        if (isset($page['child'])) {
            recursive($page['child'], $nav, true, $navItem);
        }
    }
}

$nav = new Navigation\Menu('main');
recursive($menu, $nav);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM