首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从数据库结果生成多维数组的递归函数

从数据库结果生成多维数组的递归函数
EN

Stack Overflow用户
提问于 2011-12-21 17:09:25
回答 3查看 77.3K关注 0票数 87

我希望编写一个函数,该函数接受一个页面/类别数组(从平面数据库结果中),并根据父ids生成一个嵌套的页面/类别项目数组。我想递归地做这件事,这样任何级别的嵌套都可以完成。

例如:我在一个查询中获取所有页面,下面是数据库表的样子

代码语言:javascript
复制
+-------+---------------+---------------------------+
|   id  |   parent_id   |           title           |
+-------+---------------+---------------------------+
|   1   |       0       |   Parent Page             |
|   2   |       1       |   Sub Page                |
|   3   |       2       |   Sub Sub Page            |
|   4   |       0       |   Another Parent Page     |
+-------+---------------+---------------------------+

这是我希望在我的视图文件中处理的数组:

代码语言:javascript
复制
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上有很多解决方案,但没有得到足够通用的东西,可以同时适用于页面和类别。

这是我得到的最接近的结果,但它不起作用,因为我将子代分配给第一级父代。

代码语言:javascript
复制
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);
}
EN

回答 3

Stack Overflow用户

发布于 2014-03-27 20:32:41

我知道这个问题很老,但我也面临着一个非常相似的问题--除了有大量的数据。经过一番努力,我成功地在结果集的一次传递中构建了树-使用引用。这段代码并不美观,但它运行得很好,而且运行速度很快。它是非递归的--也就是说,只有一次遍历结果集,然后在结尾处有一个array_filter

代码语言:javascript
复制
$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);

在此数据上执行时:

代码语言:javascript
复制
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生成以下输出:

代码语言:javascript
复制
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
                                (
                                )

                        )

                )

        )

)

这正是我要找的。

票数 13
EN

Stack Overflow用户

发布于 2021-09-29 12:01:53

代码语言:javascript
复制
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;
}

递归提供了太多的操作,我认为这是最好的方式。

票数 3
EN

Stack Overflow用户

发布于 2011-12-21 17:21:11

可以使用php将mysql结果放入数组中,然后使用它。

代码语言:javascript
复制
$categoryArr = Array();
while($categoryRow = mysql_fetch_array($category_query_result)){
    $categoryArr[] = array('parentid'=>$categoryRow['parent_id'],
            'id'=>$categoryRow['id']);
   }
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8587341

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档