【问题标题】:PHP Building Recursive Array from ListPHP从列表构建递归数组
【发布时间】:2011-10-26 03:47:44
【问题描述】:

我从 MySQL 数据库返回一个页面列表及其父页面,并将所有结果放入一个数组中,如下所示,其中每个结果都是一个数组,其中包括论坛的父、名称和 id(数组页面的键也与页面ID相同)。

为了模型和应用,还有一些其他的参数。

  • “根页面”的父级为 0
  • 没有孤立页面

所以,MySQL 查询将返回此数据集。

pages=>
     [1] => array(id=>1, 
                  parent=>0, 
                  name=>Hello World)
     [2] => array(id=>1, 
                  parent=>1, 
                  name=>Child of Hello World)
     [3] => array(id=>1, 
                  parent=>0, 
                  name=>Brother of Hello World)
     [4] => array(id=>4, 
                  parent=>2, 
                  name=Grand-child of Hello World)
     [6] => array(id=>6, 
                  parent=>4, 
                  name=Great-grand-child of Hello World)

然后我想将数组转换成类似这样的东西

pages=>
     [1] => id=>1, 
            name=>Hello World
            children=>

                [2] => id=>1
                       name=>Child of Hello World
                       children=>

                           [4] => 
                             id=>4
                             name=> Grand-child of Hello World)
                             children=>

                                 [6] => 
                                   id=>6
                                   name=> Great-grand-child of Hello World
                                   children= null

     [3] => array(id=>1, 
                  name=>Brother of Hello World
                  children=>null

所以基本上,我想把一个线性数组变成一个嵌套的多维数组,这样我就可以打印我的站点地图了。

它需要是一个递归解决方案。有 700 多页,最多 5 或 6 个级别。

我只想做 1 个 mysql 查询。不是 700 所以请不要给我一个基于 mysql 的解决方案。

【问题讨论】:

  • 请使用您喜欢的搜索引擎并搜索“mysql嵌套集”

标签: php arrays recursion build multidimensional-array


【解决方案1】:
<?php

$pages = array();
$pages[1] = array('id' => 1, 'parent' => 0, 'name' => 'Hello World');
$pages[2] = array('id' => 1, 'parent' => 1, 'name' => 'Child of Hello World');
$pages[3] = array('id' => 1, 'parent' => 0, 'name' => 'Brother of Hello World');
$pages[4] = array('id' => 4, 'parent' => 2, 'name' => 'Grand-child of Hello World');
$pages[6] = array('id' => 6, 'parent' => 4, 'name' => 'Great-grand-child of Hello World');

$children = array();
foreach($pages as $key => $page){
    $parent = (int)$page['parent'];
    if(!isset($children[$parent]))
        $children[$parent] = array();
    $children[$parent][$key] = array('id' => $page['id'], 'name' => $page['name']);
}

$new_pages = recursive_append_children($children[0], $children);

function recursive_append_children($arr, $children){
    foreach($arr as $key => $page)
        if(isset($children[$key]))
            $arr[$key]['children'] = recursive_append_children($children[$key], $children);
    return $arr;
}

print_r($new_pages);

?>

输出:

Array
(
    [1] => Array
        (
            [id] => 1
            [name] => Hello World
            [children] => Array
                (
                    [2] => Array
                        (
                            [id] => 1
                            [name] => Child of Hello World
                            [children] => Array
                                (
                                    [4] => Array
                                        (
                                            [id] => 4
                                            [name] => Grand-child of Hello World
                                            [children] => Array
                                                (
                                                    [6] => Array
                                                        (
                                                            [id] => 6
                                                            [name] => Great-grand-child of Hello World
                                                        )

                                                )

                                        )

                                )

                        )

                )

        )

    [3] => Array
        (
            [id] => 1
            [name] => Brother of Hello World
        )
)

【讨论】:

  • 这是 O(N) 时间复杂度,因为两个循环都可以显示为只查看数组中的每个元素一次。
  • 感谢您的回复。只是做了一些小的调整以将其调整为整个数据数组,但很好的答案谢谢。所以 $children[$parent][$key] = array('id' => $page['id'], 'name' => $page['name']);现在是 $children[$parent][$key] = $pages[$key];
  • @Partydroid 不客气。唯一不同的是,这会将 parent 值保留在结果数组中,看起来您想摆脱它。不过你也可以一直只使用unset($children[$parent][$key]['parent']);
  • @Paulpro 我知道这已经很老了,但我认为第一个 foreach 而不是 $children[$parent][$key] 它应该是 $children[$parent][$page['id']]
【解决方案2】:

这是一个构建树的快速递归函数。请注意,它不是很好(一个原因是因为它不会删除已经添加到树中的项目,所以每次你递归它都会遍历整个列表) - 但它应该足以让你开始。

function buildTree($itemList, $parentId) {
  // return an array of items with parent = $parentId
  $result = array();
  foreach ($itemList as $item) {
    if ($item['parent'] == $parentId) {
      $newItem = $item;
      $newItem['children'] = buildTree($itemList, $newItem['id']);
      $result[] = $newItem;
    }
  }

  if (count($result) > 0) return $result;
  return null;
}

$myTree = buildTree($myArray, 0);

【讨论】:

  • 感谢您的帮助。我没有使用它,但让我很好地了解了下次我将如何做。
猜你喜欢
  • 2020-01-19
  • 1970-01-01
  • 2011-11-25
  • 2014-07-17
  • 2017-02-13
  • 2023-01-28
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多