PHP数组排序树 [英] php array tree sorting

查看:96
本文介绍了PHP数组排序树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的数组。它有与编号对应母ID。我设法创建一个函数来进行排序,并把这个数组转换成一个树阵。我的问题表示,有时不正常,如果父母是孩子后工作。

I have the following array. It has a parent id that correspond with the id. I manage to create a function to sort and turn this array into a tree array. My problem stands that sometimes it does not work properly if the parent is after the child.

所以,我怎么会变成一个数组就像下面一棵树,这并不需要一个事先排好序?

So how would I turn an array like the one below to a tree that doesn't need to be sorted first?

    [0] => Array
        (
            [menu] => 
            [parent] => 0
            [id] => 1
        )
    ,
    [1] => Array
        (
            [menu] => 
            [parent] => 
            [id] => 2
        )
    ,
    [2] => Array
        (
            [menu] => 
            [parent] => 1
            [id] => 3
        )
    ,
    [3] => Array
        (
            [menu] => 
            [parent] => 1
            [id] => 4
        )
    ,
    [4] => Array
        (
            [menu] => 
            [parent] => 4
            [id] => 5
        )

我有这个功能不正常工作:

I have this function which does not work properly:

function page_tree($rows) {
    if(!is_array($rows) || empty($rows) ){
        return false;
    }
    // $rows = array();  //stores all the database rows that are to be converted into a tree
    $tree = array();  //stores the tree
    $tree_index = array();  //an array used to quickly find nodes in the tree
    $id_column = "id";  //The column that contains the id of each node
    $parent_column = "parent";  //The column that contains the id of each node's parent
    $text_column = "title";  //The column to display when printing the tree to html
    //build the tree - this will complete in a single pass if no parents are defined after children
    // vp(count($rows) );die();
    // while(count($rows) > 0){
    foreach($rows as $row_id => $row){
        $row_id = $row['id'];
        if($row[$parent_column]){
            if((!array_key_exists($row[$parent_column], $rows)) and (!array_key_exists($row[$parent_column], $tree_index))){
               unset($rows[$row_id]);
            }
            else{
              if(array_key_exists($row[$parent_column], $tree_index)){
                $parent = & $tree_index[$row[$parent_column]];
                $parent['children'][$row_id] =$row;
                $parent['children'][$row_id]["children"] = array();
                $tree_index[$row_id] = & $parent['children'][$row_id];
                unset($rows[$row_id]);
              }
            }
        }
        else{
            $tree[$row_id] = $row;
            $tree[$row_id]["children"] = array();
            $tree_index[$row_id] = & $tree[$row_id];
            unset($rows[$row_id]);
        }
    }
    // }
    return $tree;
}

请注意:其中母公司为(空)(='';),这意味着它的根

Please note: where parent is (empty) (='';) it means it's the root.

推荐答案

关键是要保持一种指数(命名为 $所有下)与所有节点引用在树上。下面的例子将增加仍然需要处理到一个名为阵列节点 $叼着并最终输出添加到 $输出阵列。

The trick is to keep a kind of index (named $all below) with references to all nodes in the tree. The example below will add nodes that still need to be processed to an array named $dangling and add the final output to the $output array.

<?
// Test input
$input = array(
array( 'menu' => 'A', 'parent' => 2, 'id' => 4),
    array( 'menu' => 'B', 'parent' => 1, 'id' => 3),
    array( 'menu' => 'C', 'parent' => 2, 'id' => 1),
    array( 'menu' => 'D', 'parent' => '', 'id' => 2)
);

$output = array();
$all = array();
$dangling = array();

// Initialize arrays
foreach ($input as $entry) {
    $entry['children'] = array();
    $id = $entry['id'];

    // If this is a top-level node, add it to the output immediately
    if ($entry['parent'] == '') {
        $all[$id] = $entry;
        $output[] =& $all[$id];

    // If this isn't a top-level node, we have to process it later
    } else {
        $dangling[$id] = $entry; 
    }
}

// Process all 'dangling' nodes
while (count($dangling) > 0) {
    foreach($dangling as $entry) {
        $id = $entry['id'];
        $pid = $entry['parent'];

        // If the parent has already been added to the output, it's
        // safe to add this node too
        if (isset($all[$pid])) {
            $all[$id] = $entry;
            $all[$pid]['children'][] =& $all[$id]; 
            unset($dangling[$entry['id']]);
        }
    }
}

print_r($output);

请注意,这将严重错误如果输入的数据是不正确(如与父母无效值的项目将导致无限循环)。

Note that this will go horribly wrong if your input data is incorrect (e.g. an item with an invalid value for parent will cause an infinite loop).

这篇关于PHP数组排序树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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