递归函数生成数据库结果多维数组 [英] Recursive function to generate multidimensional array from database result

查看:115
本文介绍了递归函数生成数据库结果多维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我期待编写一个函数,它的页/类别的数组(从一台数据库结果),并基于父IDS嵌套页/类别项目的数组。我想这样做递归,使任何级别的嵌套可以做到的。

例如:我取一个查询中的所有网页,这是什么样的数据库表看起来像

  + ------- + -------- + ------------- -------------- +
| ID | PARENT_ID |标题|
------- + -------- + + ------------------------- - +
| 1 | 0 |父页|
| 2 | 1 |子页|
| 3 | 2 |子子页|
| 4 | 0 |另一个父页|
------- + -------- + + ------------------------- - +

这是我想结束了在我的视图文件处理数组:

 阵列

    [0] =>排列
        (
            [ID] => 1
            [PARENT_ID] => 0
            [标题] =>父页
            [儿童] =>排列
                        (
                            [0] =>排列
                                (
                                    [ID] => 2
                                    [PARENT_ID] => 1
                                    [标题] =>子页
                                    [儿童] =>排列
                                                (
                                                    [0] =>排列
                                                        (
                                                            [ID] => 3
                                                            [PARENT_ID] => 1
                                                            [标题] =>子子页
                                                        )
                                                )
                                )
                        )
        )
    [1] =>排列
        (
            [ID] => 4
            [PARENT_ID] => 0
            [标题] =>另一个父页
        )

我看,并试图几乎每一个解决方案,我已经遇到(还有这里的很多人对堆栈溢出,但有没有运气得到的东西很通用,将两个网页和类别的工作。

下面是我得到的最接近,但它不工作,因为我指定给孩子的第一级父。

 函数page_walk($数组$ PARENT_ID = FALSE)
{
    $ organized_pa​​ges =阵列();    $儿童=阵列();    的foreach($数组作为$指数=> $页)
    {
        如果($页['PARENT_ID'] == 0)//没有,只是吐出来就大功告成了
        {
            $ organized_pa​​ges [$指数] = $页;
        }
        否则//如果是这样,
        {
            $ organized_pa​​ges [$ PARENT_ID] ['孩子'] [$页['身份证'] = $这个 - > page_walk($页,$ PARENT_ID);
        }
    }    返回$ organized_pa​​ges;
}功能page_list($数组)
{
    $ fakepages =阵列();
    $ fakepages [0] =阵列('ID'=大于1,'PARENT_ID'=大于0,'标题'=>'父页');
    $ fakepages [1] =阵列('ID'=大于2,'PARENT_ID'=大于1,'标题'=>'子页');
    $ fakepages [2] =阵列('ID'= GT; 3,PARENT_ID'=大于2,'标题'=>'子子页');
    $ fakepages [3] =阵列('ID'=> 4,PARENT_ID'= GT; 3,'标题'=>'另一个父页');    $页= $这 - > page_walk($ fakepages,0);    的print_r($页);
}


解决方案

一些很简单的,一般树楼:

 函数buildTree(数组元素$,$ parentId的= 0){
    $分公司=阵列();    的foreach($元素作为$元素){
        如果($元素['PARENT_ID'] == $ parentId的){
            $儿童= buildTree($元素,$元素['身份证']);
            如果($子女){
                $元素['孩子'] = $儿童;
            }
            $分支[] = $元素;
        }
    }    返回$分公司;
}$树= buildTree($行);

该算法是pretty简单:


  1. 以所有元素的数组和当前父(的id最初 0 /没有/ /等等)。

  2. 遍历所有元素。

  3. 如果在 PARENT_ID 元素的匹配您在第1拿到了当前父ID,该元素是父的孩子。把它放在你当前的儿童(此处为: $分支)的列表。

  4. 递归调用函数与您刚才在第3标识的元素,即的ID发现元素的所有孩子,并把它们添加为孩子元素。

  5. 返回您发现孩子的名单。

在换句话说,这种函数的一次执行返回它们是给定父ID的子元素的列表。与 buildTree调用它($ myArray的,1),它将返回具有父ID 1.最初,这个函数调用父ID为0元素的列表,所以没有父母的id元素被退回,这是根节点。该函数递归调用自己找到孩子的孩子。

I'm looking to write a function that takes an array of pages/categories (from a flat database result) and generates an array of nested page/category items based on the parent ids. I would like to do this recursively, so that any level of nesting can be done.

For example: I'm fetching all the pages in one query, and this is the what the database table looks like

+-------+---------------+---------------------------+
|   id  |   parent_id   |           title           |
+-------+---------------+---------------------------+
|   1   |       0       |   Parent Page             |
|   2   |       1       |   Sub Page                |
|   3   |       2       |   Sub Sub Page            |
|   4   |       0       |   Another Parent Page     |
+-------+---------------+---------------------------+

And this is the array I would like to end up with to process in my view files:

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
        )
)

I've looked and tried nearly every solution I've come across (there's a lot of them here on Stack Overflow, but have had no luck getting something generic enough that will work for both pages and categories.

Here's the closest I've gotten, but it doesn't work because I'm assigning the children to the first level parent.

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);
}

解决方案

Some very simple, generic tree building:

function buildTree(array $elements, $parentId = 0) {
    $branch = array();

    foreach ($elements as $element) {
        if ($element['parent_id'] == $parentId) {
            $children = buildTree($elements, $element['id']);
            if ($children) {
                $element['children'] = $children;
            }
            $branch[] = $element;
        }
    }

    return $branch;
}

$tree = buildTree($rows);

The algorithm is pretty simple:

  1. Take the array of all elements and the id of the current parent (initially 0/nothing/null/whatever).
  2. Loop through all elements.
  3. If the parent_id of an element matches the current parent id you got in 1., the element is a child of the parent. Put it in your list of current children (here: $branch).
  4. Call the function recursively with the id of the element you have just identified in 3., i.e. find all children of that element, and add them as children element.
  5. Return your list of found children.

In other words, one execution of this function returns a list of elements which are children of the given parent id. Call it with buildTree($myArray, 1), it will return a list of elements which have the parent id 1. Initially this function is called with the parent id being 0, so elements without parent id are returned, which are root nodes. The function calls itself recursively to find children of children.

这篇关于递归函数生成数据库结果多维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆