如何确定父/子阵列中的特定级别?

时间:2012-11-13 16:11:43

标签: php treeview

我循环遍历一组数组,每个元素都包含一个父ID。

$currentparent = $group['grpId']; //$group is the current element in a loop wrapped around this piece of code
$currentlevel = 0;

foreach($groups as $grp)
{
    $parent = $grp['grpParentId'];

    if($parent != $currentparent && $currentlevel != 6)
    {
        //adding layer
        $currentlevel++;
        //changing parent
        $currentparent = $grp['grpParentId'];
    }

    if($currentlevel == 6)
    {
        //call a special function
    }
    else
    {
        //call the regular function
    }
}

这样可以在这样的数组上正常工作:

group
-group
--group
---group
----group
----- group <- the only group on the 5th layer

但不是在第5级有多个组的数组:

group
-group
--group
--group
---group
----group
-----group <- 5th layer
----group
-----group <- 5th layer too, but diff parent

如果在数组的第五层有多个具有多个父项的组,我该如何解决此问题以获取调用的特殊函数?

我希望我能够清楚地表达我的问题。

2 个答案:

答案 0 :(得分:1)

尝试遍历各组,始终搜索其级别可由其父级确定的组。像这样:

// example input
$groups = array(
    array('grpParentId' => 0, 'grpId' => 1, ),
    array('grpParentId' => 1, 'grpId' => 2, ),
    array('grpParentId' => 2, 'grpId' => 3, ),
    array('grpParentId' => 3, 'grpId' => 4, ),
    array('grpParentId' => 4, 'grpId' => 5, ),
    array('grpParentId' => 5, 'grpId' => 6, ),
    array('grpParentId' => 6, 'grpId' => 7, ),

    array('grpParentId' => 5, 'grpId' => 8, ),
    array('grpParentId' => 8, 'grpId' => 9, ),
);


shuffle($groups); // just for testing the logic does in fact tolerate randomly ordered input

$rootId = 1; // set to the rootnode's id
$grouplevels = array();

// find the rootnode first
foreach($groups as $i => $grp) {
    if ($rootId == $grp['grpId']) {
        $grouplevels[$rootId] = 1;
        unset($groups[$i]);
        break;
    }
}

// figure out childgroup levels
do {
    $old_count = count($groups);
    foreach($groups as $i => $grp) {
        if (in_array($grp['grpParentId'], array_keys($grouplevels))) {
            // the current node's parent's level was determinated previously, we can tell this group's level as well
            $grouplevels[$grp['grpId']] = $level = $grouplevels[$grp['grpParentId']]+1;

            if ($level == 6) {
                print $grp['grpId']."\n";
            }

            // remove from the "we dont know yet" list
            unset($groups[$i]);
        }
    }
} while (count($groups) < $old_count); // run while we can sort out at least one group's level in the current iteration

// handle the case when not every group's level could been determinated!
if (!empty($groups)) {
    print "inconsitency ahead!";
}

答案 1 :(得分:0)

可以使用递归模式解决。以下代码应该可以解决问题。它可能会被优化。

$currentparent = $group['grpId']; //$group is the current element in a loop wrapped around         
$this piece of code
$currentlevel = 0;

// Initialize 
foreach($groups as $grp)
{
    $grp['children'] = array();

}

foreach($groups as $grp)
{
    $parent = $grp['grpParentId'];
    $parent['children'][] = $grp;  
}

foreach($groups as $grp)
{
    if(empty($parent['children'])) $root = $grp; // Alternatively check if parent is null or something. 
}


function recursive_count($root, $lvl = 0)
{
    if($currentlevel == 6)
    {
        //call a special function
    }
    else
    {
        //call the regular function
    }
    foreach($root['children'] as $children)
    {
       recursive_count($children, $lvl++);
    }


 }

 recursive_count($root);

更新:如果内存消耗有问题,可以在将子组添加到子阵列时使用引用。

更新II:即使该算法有4个foreach和一个递归结构,运行时间仍为O(n),其中n是图的大小。