我希望编写一个函数,该函数接受一个页面/类别数组(从平面数据库结果中),并根据父ids生成一个嵌套的页面/类别项目数组。我想递归地做这件事,这样任何级别的嵌套都可以完成。
例如:我在一个查询中获取所有页面,下面是数据库表的样子
+-------+---------------+---------------------------+
| id | parent_id | title |
+-------+---------------+---------------------------+
| 1 | 0 | Parent Page |
| 2 | 1 | Sub Page |
| 3 | 2 | Sub Sub Page |
| 4 | 0 | Another Parent Page |
+-------+---------------+---------------------------+
这是我希望在我的视图文件中处理的数组:
Array
(
[0] => Array
(
[id] => 1
[parent_id] => 0
[title] => Parent Page
[children] => Array
(
[0] => Array
(
[id] => 2
[parent_id] => 1
[title] => Sub Page
[children] => Array
(
[0] => Array
(
[id] => 3
[parent_id] => 1
[title] => Sub Sub Page
)
)
)
)
)
[1] => Array
(
[id] => 4
[parent_id] => 0
[title] => Another Parent Page
)
)
我已经看过并尝试过我遇到的几乎所有的解决方案(在Stack Overflow上有很多解决方案,但没有得到足够通用的东西,可以同时适用于页面和类别。
这是我得到的最接近的结果,但它不起作用,因为我将子代分配给第一级父代。
function page_walk($array, $parent_id = FALSE)
{
$organized_pages = array();
$children = array();
foreach($array as $index => $page)
{
if ( $page['parent_id'] == 0) // No, just spit it out and you're done
{
$organized_pages[$index] = $page;
}
else // If it does,
{
$organized_pages[$parent_id]['children'][$page['id']] = $this->page_walk($page, $parent_id);
}
}
return $organized_pages;
}
function page_list($array)
{
$fakepages = array();
$fakepages[0] = array('id' => 1, 'parent_id' => 0, 'title' => 'Parent Page');
$fakepages[1] = array('id' => 2, 'parent_id' => 1, 'title' => 'Sub Page');
$fakepages[2] = array('id' => 3, 'parent_id' => 2, 'title' => 'Sub Sub Page');
$fakepages[3] = array('id' => 4, 'parent_id' => 3, 'title' => 'Another Parent Page');
$pages = $this->page_walk($fakepages, 0);
print_r($pages);
}
发布于 2014-03-27 20:32:41
我知道这个问题很老,但我也面临着一个非常相似的问题--除了有大量的数据。经过一番努力,我成功地在结果集的一次传递中构建了树-使用引用。这段代码并不美观,但它运行得很好,而且运行速度很快。它是非递归的--也就是说,只有一次遍历结果集,然后在结尾处有一个array_filter
:
$dbh = new PDO(CONNECT_STRING, USERNAME, PASSWORD);
$dbs = $dbh->query("SELECT n_id, n_parent_id from test_table order by n_parent_id, n_id");
$elems = array();
while(($row = $dbs->fetch(PDO::FETCH_ASSOC)) !== FALSE) {
$row['children'] = array();
$vn = "row" . $row['n_id'];
${$vn} = $row;
if(!is_null($row['n_parent_id'])) {
$vp = "parent" . $row['n_parent_id'];
if(isset($data[$row['n_parent_id']])) {
${$vp} = $data[$row['n_parent_id']];
}
else {
${$vp} = array('n_id' => $row['n_parent_id'], 'n_parent_id' => null, 'children' => array());
$data[$row['n_parent_id']] = &${$vp};
}
${$vp}['children'][] = &${$vn};
$data[$row['n_parent_id']] = ${$vp};
}
$data[$row['n_id']] = &${$vn};
}
$dbs->closeCursor();
$result = array_filter($data, function($elem) { return is_null($elem['n_parent_id']); });
print_r($result);
在此数据上执行时:
mysql> select * from test_table;
+------+-------------+
| n_id | n_parent_id |
+------+-------------+
| 1 | NULL |
| 2 | NULL |
| 3 | 1 |
| 4 | 1 |
| 5 | 2 |
| 6 | 2 |
| 7 | 5 |
| 8 | 5 |
+------+-------------+
最后一个print_r
生成以下输出:
Array
(
[1] => Array
(
[n_id] => 1
[n_parent_id] =>
[children] => Array
(
[3] => Array
(
[n_id] => 3
[n_parent_id] => 1
[children] => Array
(
)
)
[4] => Array
(
[n_id] => 4
[n_parent_id] => 1
[children] => Array
(
)
)
)
)
[2] => Array
(
[n_id] => 2
[n_parent_id] =>
[children] => Array
(
[5] => Array
(
[n_id] => 5
[n_parent_id] => 2
[children] => Array
(
[7] => Array
(
[n_id] => 7
[n_parent_id] => 5
[children] => Array
(
)
)
[8] => Array
(
[n_id] => 8
[n_parent_id] => 5
[children] => Array
(
)
)
)
)
[6] => Array
(
[n_id] => 6
[n_parent_id] => 2
[children] => Array
(
)
)
)
)
)
这正是我要找的。
发布于 2021-09-29 12:01:53
public function testTree(){
$array = [
['id'=>7,'parent_id'=>3],
['id'=>1,'parent_id'=>0],
['id'=>2,'parent_id'=>0],
['id'=>3,'parent_id'=>1],
['id'=>4,'parent_id'=>1],
['id'=>5,'parent_id'=>2],
['id'=>6,'parent_id'=>1],
['id'=>8,'parent_id'=>4],
['id'=>9,'parent_id'=>4],
['id'=>10,'parent_id'=>0]
];
$res = $this->buildTree($array);
print_r($res);
}
public function buildTree($array,$id_key = 'id',$parent_key = 'parent_id'){
$res = [];
foreach($array as $y){
$array_with_id[$y[$id_key]] = $y;
}
foreach($array_with_id as $key => $element){
if($element[$parent_key]){
$array_with_id[$element[$parent_key]]['childrens'][$key] = &$array_with_id[$key];
}else{
$res[$element[$id_key]] = &$array_with_id[$key];
}
}
return $res;
}
递归提供了太多的操作,我认为这是最好的方式。
发布于 2011-12-21 17:21:11
可以使用php将mysql结果放入数组中,然后使用它。
$categoryArr = Array();
while($categoryRow = mysql_fetch_array($category_query_result)){
$categoryArr[] = array('parentid'=>$categoryRow['parent_id'],
'id'=>$categoryRow['id']);
}
https://stackoverflow.com/questions/8587341
复制相似问题