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 には、必要な結果を生成するために反復できる子ノードを持つ要素が含まれているはずです。

これは、現在の配列をループして、親ノードとその子ノードを識別し、それらを整理することで機能します。2 レベルの深さでのみ機能します。さらに深く掘り下げる必要がある場合は、コードを整理して整理する必要があるかもしれません。

于 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 に答える