【问题标题】:How to create a ul - li menu from a tree like array?如何从树状数组创建 ul - li 菜单?
【发布时间】:2014-01-30 09:17:38
【问题描述】:

我有一个带有titlechildren 索引的数组。

title 始终不为空。 children 是一个数组,为空或非空。

任何children 都有titlechildren 等等。

$myArray = [
    0 => [
        'title'    => 'N1',
        'children' =>
            [
                0 =>
                    [
                        'title'    => 'N11',
                        'children' =>
                            [
                                0 =>
                                    [
                                        'title'    => 'N111',
                                        'children' => [],
                                    ],
                            ],
                    ],
            ],
    ],
    1 =>
        [
            'title'    => 'N2',
            'children' =>
                [
                    0 =>
                        [
                            'title'    => 'N21',
                            'children' =>
                                [],
                        ],
                ],
        ],
];

现在,我想用这个数组创建一个下拉菜单。

我在从这个数组创建无序列表(ulli)时遇到问题。

我希望我的结果是这样的:

<ul>
    <li>N1
        <ul>
            <li>N11
                <ul>
                    <li>N111</li>
                </ul>
            </li>
        </ul>
    </li>
    <li>N2
        <ul>
            <li>N21</li>
        </ul>
    </li>
</ul>

【问题讨论】:

  • 好吧,问题说得很好。你有任何代码吗?首先,您需要一个带有foreach 循环的函数,然后要完成它,它需要是递归的。
  • 初始代码中的问题是 printMenu 函数中的 $array 和 $item 变量引用了最顶层运行的值。执行以下操作(在递归函数之外循环)
  • 啊,你确实有过初步尝试——为什么要删除它?
  • 因为我认为它愚蠢地无关紧要,对不起

标签: php arrays recursion


【解决方案1】:

我相信这会奏效:

    function menu($arr) {
        echo "<ul>";
        foreach ($arr as $val) {

            if (!empty($val['children'])) {
                echo "<li>" . $val['title'];
                menu($val['children']);
                echo "</li>";
            } else {
                echo "<li>" . $val['title'] . "</li>";
            }
        }
        echo "</ul>";
    }

【讨论】:

  • 这不是创建两个根ul 而不是像 OP 预期结果中那样只创建一个吗?
  • 投了反对票,因为你是从函数中呼应!
【解决方案2】:

假设这是你的数组

$menu = array(
    array(
        'title'=>'N1',
        'children'=>array(
                'title'=>'N11',
                'children'=>array(
                        'title'=>'N111',
                        'children'=>array(),
                ),
        ),
    ),
    array(
        'title'=>'N2',
        'children'=>array(
                'title'=>'N21',
                'children'=>array(),
                )
    ),
);

你可以利用递归来构建这个 HTML 结构。

    function createMenu($arr){
      $str = '';
      if(is_array($arr)){
             $str .= "<li>".$arr['title'];
         if(!empty($arr['children'])){
        $str .="<ul>";
        $str .= createMenu($arr['children'],$str);                   
        $str .="</ul>";
         }
         $str .= "</li>";               
      }
     return $str;  
   }

现在调用递归函数来创建 HTML

$myMenu ='';
foreach($menu as $arr){
  $myMenu .= createMenu($arr);
}
echo "<ul>".$myMenu."</ul>";
exit();

【讨论】:

  • 从广义上讲,这是一个很好的答案(尽管我认为函数应该返回值而不是使用传递引用参数)。但是,您没有鼓励 OP 自己思考问题,而是将答案放在盘子上。这解决了他们眼前的问题,但我不确定它他们什么。
  • @hafler 我已经更新了我的代码。对于给您带来的任何不便,我深表歉意.. :)
【解决方案3】:

我必须实现类似的东西,但我希望 HTML 生成位于 twig 模板中。这可能如下所示:

{% macro printMenuElements(nestedListElements, level = 0, parent = 'root') %}
    <ul>
        {% for nestedElement in  nestedListElements %}
            {% set children  = nestedElement.children %}
            {% set title = nestedElement.title %}


            {% if children is not empty and children is iterable %}
                <li data-parent="{{ parent }}">
                    {{ title }}
                    {{ _self.printMenuElements(children, level +1, title) }}
                </li>
            {% else %}
                <li data-parent="{{ parent }}">
                    {{ title }}
                </li>
            {% endif %}
        {% endfor %}
    </ul>
{% endmacro %}

{% block body %}
    <h1>Menu</h1>
    {% import _self as helper %}
    {{ helper.printMenuElements(yourArray) }}
{% endblock %}

生成以下 HTML 输出:

<ul>
    <li data-parent="root">
        N1
        <ul>
            <li data-parent="N1">
                N11
                <ul>
                    <li data-parent="N11">
                        N111
                    </li>
                </ul>
            </li>
        </ul>
    </li>
    <li data-parent="root">
        N2
        <ul>
            <li data-parent="N2">
                N21
            </li>
        </ul>
    </li>
</ul>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 2021-10-06
    • 2022-12-20
    相关资源
    最近更新 更多