Php 多维数组递归

Php 多维数组递归,php,arrays,recursion,multidimensional-array,Php,Arrays,Recursion,Multidimensional Array,我已经在这方面工作了很长时间,我得到了我想要的工作,但我认为有更简单的解决方案 到目前为止,我得到了这个: $menu = array( 0 => (object) array( 'cat_id' => 1, 'cat_parent' => 0, 'cat_name' => 'domov', 'cat_href' => 'domov', 'cat_subcategories'

我已经在这方面工作了很长时间,我得到了我想要的工作,但我认为有更简单的解决方案

到目前为止,我得到了这个:

$menu = array(
    0 => (object) array(
        'cat_id'   => 1,
        'cat_parent' => 0,
        'cat_name' => 'domov',
        'cat_href' => 'domov',
        'cat_subcategories' => array()
    ),
    1 => (object) array(
        'cat_id'   => 2,
        'cat_parent' => 0,
        'cat_name' => 'clanky',
        'cat_href' => 'clanky',
        'cat_subcategories' => array(
            0 => (object) array(
                'cat_id'   => 9,
                'cat_parent' => 2,
                'cat_name' => 'apple clanky',
                'cat_href' => 'apple',
                'cat_subcategories' => array(
                    0 => (object) array(
                        'cat_id'   => 11,
                        'cat_parent' => 9,
                        'cat_name' => 'iphone clanky',
                        'cat_href' => 'iphone',
                        'cat_subcategories' => array()
                    ),
                    1 => (object) array(
                        'cat_id'   => 12,
                        'cat_parent' => 9,
                        'cat_name' => 'macbook clanky',
                        'cat_href' => 'macbook',
                        'cat_subcategories' => array()
                    )
                )
            ),
            1 => (object) array(
                'cat_id'   => 10,
                'cat_parent' => 2,
                'cat_name' => 'microsoft clanky',
                'cat_href' => 'microsoft',
                'cat_subcategories' => array()
            ),
        )
    ),
    2 => (object) array(
        'cat_id'   => 3,
        'cat_parent' => 0,
        'cat_name' => 'produkty',
        'cat_href' => 'produkty',
        'cat_subcategories' => array()
    ),
    3 => (object) array(
        'cat_id'   => 4,
        'cat_parent' => 0,
        'cat_name' => 'vyrobcovia',
        'cat_href' => 'vyrobcovia',
        'cat_subcategories' =>
            array(
                0 => (object) array(
                    'cat_id'   => 5,
                    'cat_parent' => 4,
                    'cat_name' => 'apple',
                    'cat_href' => 'apple',
                    'cat_subcategories' => array(
                        0 => (object) array(
                            'cat_id'   => 7,
                            'cat_parent' => 5,
                            'cat_name' => 'iphone',
                            'cat_href' => 'iphone',
                            'cat_subcategories' => array()
                        ),
                        1 => (object) array(
                            'cat_id'   => 8,
                            'cat_parent' => 5,
                            'cat_name' => 'macbook',
                            'cat_href' => 'macbook',
                            'cat_subcategories' => array()
                        )
                    )
                ),
                1 => (object) array(
                    'cat_id'   => 6,
                    'cat_parent' => 4,
                    'cat_name' => 'microsoft',
                    'cat_href' => 'microsoft',
                    'cat_subcategories' => array()
                ),
            )
    ),
);
function generate_menu($menu, $level = 1, $tmp_array = array())
{
    foreach($menu as $key => $c)
    {
        $menu_item = get_menu_elements($c, $level);
        $tmp_array = array_replace_recursive($tmp_array, $menu_item);

        foreach($c->cat_subcategories as $_key => $_c)
        {
            $menu_item = get_menu_elements($_c, $level+1);
            $tmp_array = array_replace_recursive($tmp_array, $menu_item);

            foreach($_c->cat_subcategories as $__key => $__c)
            {
                $menu_item = get_menu_elements($__c, $level+2);
                $tmp_array = array_replace_recursive($tmp_array, $menu_item);
            }

        }
    }

    return $tmp_array;
}

function get_menu_elements($c, $level = 1)
{

    $level_var   = "level_".($level);


    $output = array(
        $level_var => array()
    );



    $output[$level_var][$c->cat_id] = array(
        'parent' => $c->cat_parent,
        'html'   => $c->cat_name
    );

    return $output;

}
最后,我应该使用多维数组:

array(3) {
  ["level_1"]=>
  array(4) {
    [1]=>
    array(2) {
      ["parent"]=>
      int(0)
      ["html"]=>
      string(5) "domov"
    }
    [2]=>
    array(2) {
      ["parent"]=>
      int(0)
      ["html"]=>
      string(6) "clanky"
    }
    [3]=>
    array(2) {
      ["parent"]=>
      int(0)
      ["html"]=>
      string(8) "produkty"
    }
    [4]=>
    array(2) {
      ["parent"]=>
      int(0)
      ["html"]=>
      string(10) "vyrobcovia"
    }
  }
  ["level_2"]=>
  array(4) {
    [9]=>
    array(2) {
      ["parent"]=>
      int(2)
      ["html"]=>
      string(12) "apple clanky"
    }
    [10]=>
    array(2) {
      ["parent"]=>
      int(2)
      ["html"]=>
      string(16) "microsoft clanky"
    }
    [5]=>
    array(2) {
      ["parent"]=>
      int(4)
      ["html"]=>
      string(5) "apple"
    }
    [6]=>
    array(2) {
      ["parent"]=>
      int(4)
      ["html"]=>
      string(9) "microsoft"
    }
  }
  ["level_3"]=>
  array(4) {
    [11]=>
    array(2) {
      ["parent"]=>
      int(9)
      ["html"]=>
      string(13) "iphone clanky"
    }
    [12]=>
    array(2) {
      ["parent"]=>
      int(9)
      ["html"]=>
      string(14) "macbook clanky"
    }
    [7]=>
    array(2) {
      ["parent"]=>
      int(5)
      ["html"]=>
      string(6) "iphone"
    }
    [8]=>
    array(2) {
      ["parent"]=>
      int(5)
      ["html"]=>
      string(7) "macbook"
    }
  }
}
我想打印多级菜单递归。我用这段代码得到了它,但在函数generate_菜单中,我不得不对cat_子类别使用3个foreach循环。当我像这样使用递归时:

function generate_menu($menu, $level = 1, $tmp_array = array())
{
    foreach($menu as $key => $c)
    {
        $menu_item = get_menu_elements($c, $level);
        $tmp_array = array_replace_recursive($tmp_array, $menu_item);

        if (!empty($c->cat_subcategories)) generate_menu($c->cat_subcategories, $level + 1, $tmp_array);
    }

    return $tmp_array;
}
我的输出只有“1级”

我现在得到的输出和我想要的一样,我只想简化multipleforeach()

等等

第1级-$menu的第一个循环 级别_2-cat_子类别的循环
级别3-cat_子类别项的cat_子类别循环

我不久前使用了此函数。它可以帮助你

我有一个数组,其中$arr[实际物品][家长id]

function getChild($id, $result, $count) {
    for( $i = 0; $i < sizeof($result); $i ++) {
        if( $result[$i][2] == $id) {
            getChild($result[$i][0], $result, $count + 1);
        }
    }
}
函数getChild($id,$result,$count){ 对于($i=0;$i 编辑
在我的例子中,一维数组中的所有项目,但具有n维数组的层次结构取决于父id。

编码到打印菜单

此代码适用于N个层次结构

 static function printAllCategoriesAsCheckbox($arr, $d=0){

    $htmlString = "";

    if (is_array($arr)){
        foreach($arr as $category){

            $htmlString = $htmlString . '<div><input style="margin-left: ' . 30*$d . 'px;" value="'.$category->id.'" class="category-input" type="checkbox" name="category_id[]">';

            $htmlString = $htmlString . ' <label for="category_'.$category->id.'">' . $category->name . '</label></div>';


            if (is_array($category['childs'])){
                $htmlString = $htmlString . ItemCategory::printAllCategoriesAsCheckbox($category['childs'], $d+1);
            }
        }
    }

    return $htmlString;
}
静态函数printAllCategoriesScheckBox($arr,$d=0){
$htmlString=“”;
if(is_数组($arr)){
foreach($arr作为$category){
$htmlString=$htmlString'';
$htmlString=$htmlString'.$category->name'.';
if(是_数组($category['childs'])){
$htmlString=$htmlString.ItemCategory::PrintAllCategoriesScheckBox($category['childs',$d+1);
}
}
}
返回$htmlString;
}

您基本上需要在菜单树中执行宽度优先遍历。为此,我建议使用迭代函数而不是递归函数,因为后者更适合深度优先遍历

以下是函数:

function generate_menu($menu) {
    $result = [];

    $level = 1;
    while (count($menu)) {
        $queue = [];
        $items = [];
        foreach($menu as $cat) {
            $items[$cat->cat_id] = [
                "parent" => $cat->cat_parent,
                "html" => $cat->cat_name
            ];
            $queue = array_merge($queue, $cat->cat_subcategories);
        }
        $result["level_$level"] = $items;
        $level++;
        $menu = $queue;
    }
    return $result;
}
看它继续跑


当此函数遍历树的顶层时,它将所有子级收集到
$queue
中。将顶层转换为输出后(在
level_1
键中),该队列将包含所有第二级条目。然后移动到
$菜单
,重复该过程,但现在是
级别2
。这将继续进行,直到达到一个级别,在该级别中找不到更多条目

请为示例输入提供所需的输出。不清楚您希望
..
级别1
级别2
级别3
之后是什么。另外,什么是
get_menu_elements
?编辑,该函数使用菜单模板获取html文件,我只是基本上在html中解析数据库中的数据。这个结构正在工作,我只是觉得generate_菜单中的那些循环不必要,我想它们可能会变得简单。我正在尝试理解输出,但我立即想知道为什么
domov
不会出现在您想要的输出中。也许我很天真,但这只是你想要的一部分吗?如果是的话,你能再加一点吗?如果可以的话,我会运行你的代码,但我没有
get\u level\u模板
。是的,这只是我没有代码的一部分。我编辑了代码,所以你可以运行它还包括整个输出不是我的情况,我只需要编辑我的代码,所以我不必使用3个循环,但递归,因为我想使用我的templates@DeiForm它完全符合你的模板。我看到了你的投入。你不需要3个循环我不想要字符串作为重注册值不是我的情况我只需要编辑我的代码,所以我不需要使用3个循环,但是递归因为我想使用我的模板谢谢我想先收集顶级项目,但不知道如何处理子类别:D谢谢