我在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>
答案 0 :(得分: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现在应该包含具有子节点的元素,您可以迭代它们以产生所需的结果。
这是通过循环当前数组,识别父项及其子节点并按此组织它们来实现的。只会工作两个层次;如果你需要更深入,代码可能需要重新加工以更好地组织它。
答案 1 :(得分: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;
}
必须有一个更好的方法来解决这类问题。
答案 2 :(得分: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>';
}
}
?>