1

我在 WP 中有一个充满导航菜单项的平面数组。每个项目都知道它的父母,但他们似乎都不知道他们是否有孩子。

            Array
(
    [0] => stdClass Object
        (
            [ID] => 22
            [menu_item_parent] => 0
        )
    [1] => stdClass Object
        (
            [ID] => 108
            [menu_item_parent] => 22
        )
    [2] => stdClass Object
        (
            [ID] => 117
            [menu_item_parent] => 108
        )
    [3] => stdClass Object
        (
            [ID] => 118
            [menu_item_parent] => 108
        )
    [4] => stdClass Object
        (
            [ID] => 106
            [menu_item_parent] => 22
        )
    [5] => stdClass Object
        (
            [ID] => 119
            [menu_item_parent] => 106
        )
    [6] => stdClass Object
        (
            [ID] => 120
            [menu_item_parent] => 106
        )
    [7] => stdClass Object
        (
            [ID] => 23
            [menu_item_parent] => 0
        )
)

我已经尝试用几种不同的方式用条件逻辑来处理它(每次都硬编码值并不理想),但我一直把自己编码成一团糟。如何遍历数组以产生这样的结果?

<ul>
    <li>22
        <ul class="child">
            <li>108
                <ul class="grandchild">
                    <li>117</li>
                    <li>118</li>
                </ul>
            </li>
            <li>106
                <ul class="grandchild">
                    <li>119</li>
                    <li>120</li>
                </ul>
            </li>           
        </ul>
    </li>
    <li>23</li>
</ul>
4

3 回答 3

1

您需要识别节点的子节点,以便可以将它们放入所需的结构中。为此,您需要遍历元素并重新组织它们。下面是一个粗略的代码;没有测试它。

$new = array();

foreach ($array as $elm)
{
    if ($elm->menu_item_parent != 0)
    {
        foreach($new as $it)
        {
            $found = false;
            if ($it->ID == $elm->menu_item_parent)
            {
                $it->children[] = $elm;
                $found = true; // Found the parent break loop
            } else if (isset($it->children))
            {
                foreach ($it->children as $child)
                {
                    if ($child->ID == $elm->menu_item_parent)
                    {
                        $child->children[] == $elm;
                        $found = true;
                        break;
                    }
                }

                if ($found) break;
            }
        }
    } else {
        $new[] = $elm; // Parent element - add directly
    }
}

数组 $new 现在应该包含带有子节点的元素,您可以对其进行迭代以产生所需的结果。

这通过循环当前数组、识别父节点及其子节点并将它们组织起来来工作。只能工作两层;如果您需要更深入,代码可能需要重新编写以更好地组织它。

于 2012-11-27T10:46:02.557 回答
1

我想从制作单独的父(主)数组和子数组开始(或者我们可以使它成为一个长的多维数组)

foreach($arr AS $value)
{
    if($value->menu_item_parent == 0)
        $parentArr[] = $value->ID;
    else
        $childArr[$value->menu_item_parent][] = $value->ID; 
}

递归函数将有助于获得一点全局解决方案来生成子孙。考虑到这一点,

$str = '';

echo "<ul>";
foreach($parentArr AS $pValue)
{
    echo '<li>'.$pValue;
        if(in_array($pValue, array_keys($childArr)))
        {
            echo '<ul class="child">';
            $result= childs($pValue); //calling a recursive function (In case one have larger child tree)
            echo $result;
            echo '</ul>';
        }
    echo '</li>';
}
echo '</ul>';

function childs($val)
{
    global $childArr;
    global $str;

    foreach($childArr[$val] AS $cValue)
    {
        $str.= '<li>'.$cValue;

        if(in_array($cValue, array_keys($childArr)))
        {
            $str.= '<ul class="grand_child">';
            childs($cValue);
            $str.= '</ul>';
        }
        $str.= '</li>';
    }

    return $str;
}

必须有更好的方法来处理此类问题。

于 2012-11-27T13:25:41.020 回答
0

我最终这样做了:

<?php 
$items = wp_get_nav_menu_items('primary'); // original flat array
foreach ($items as $item) {
    $pages[$item->menu_item_parent][] = $item; // create new array
}
foreach ($pages[0] as $parent) {
    if (isset($pages[$parent->ID])) { // if page has children
        echo '<li>'.$parent->ID;
        echo '<ul class="children">';
        foreach ($pages[$parent->ID] as $child) {
            if (isset($pages[$child->ID])) { // child has children
                echo '<li>'.$child->ID;
                echo '<ul class="grandchildren">';
                foreach ($pages[$child->ID] as $grandchild) {
                    echo '<li>'.$grandchild->ID.'</li>';
                }
                echo '</ul></li>';
            } else {
                echo '<li>'.$child->ID.'</li>'; // child has no children
            }
        }
        echo '</ul></li>';
    } else { // page has no children
        echo '<li>'.$parent->ID.'</li>';
    }
}
?>
于 2012-11-27T16:02:07.737 回答