** 更新 #2 - 我使用引用(不是递归)重新设计。这只需要一次通过数据。如果每个父项或子项尚不存在,则将其作为顶级项添加到数组(在本例中为 $a)。这个顶级项目的关键是父母或孩子的名字。该值是一个数组,其中包含对其子级顶级项的引用。此外,创建第二个数组 ($p),仅引用第一个数组 ($a) 中的父项。在一个非常快速的单遍中,所有的关系都被发现了。
代码(更新 #2):
<?php
$tree_base = array(
array('parent' => 'parentA','name' => 'child1'),
array('parent' => 'parentB','name' => 'childC'),
array('parent' => 'parentA','name' => 'child2'),
array('parent' => 'parentC','name' => 'child3'),
array('parent' => 'child1','name' => 'child4'),
array( 'parent' => 'child4', 'name' => 'child5'),
array( 'parent' => 'DataSelect', 'name' => 'getBaseUri'),
array( 'parent' => 'getBaseUri', 'name' => 'getKbBaseURI')
);
$tree = parseTree($tree_base);
echo '<pre>'.print_r($tree, TRUE).'</pre>';
showresults($tree);
function parseTree($tree){
$a = array();
foreach ($tree as $item){
if (!isset($a[$item['name']])){
// add child to array of all elements
$a[$item['name']] = array();
}
if (!isset($a[$item['parent']])){
// add parent to array of all elements
$a[$item['parent']] = array();
// add reference to master list of parents
$p[$item['parent']] = &$a[$item['parent']];
}
if (!isset($a[$item['parent']][$item['name']])){
// add reference to child for this parent
$a[$item['parent']][$item['name']] = &$a[$item['name']];
}
}
return $p;
}
function showresults($tree, &$loop = array()){
if (is_array($tree) & count($tree) > 0){
echo "<table>";
echo "<tr>";
foreach ($tree as $key => $children){
// prevent endless recursion
if (!array_key_exists($key, $loop)){
$loop[$key] = null;
echo "<tr>";
echo "<td style='border:1px solid'>";
echo $key;
echo "<td style='border:1px solid'>";
showresults($children, $loop);
echo "</td>";
echo "</td>";
echo "</tr>";
}
}
echo "</tr>";
echo "</table>";
}
}
?>
输出(更新#2):
Array
(
[parentA] => Array
(
[child1] => Array
(
[child4] => Array
(
[child5] => Array
(
)
)
)
[child2] => Array
(
)
)
[parentB] => Array
(
[childC] => Array
(
)
)
[parentC] => Array
(
[child3] => Array
(
)
)
[DataSelect] => Array
(
[getBaseUri] => Array
(
[getKbBaseURI] => Array
(
)
)
)
)
**更新 #1 - 我已修复代码以显示多级子级(以及您的新示例数组结构)。为了保持干净,我只使用生成的数组元素的键来存储父项和子项的名称。表格输出在视觉上变得更加复杂。我为每个父/子组使用了一行,第一列为父组,第二列为其子组。这也是递归的,因此包含子项的列可以在相同格式的新表中显示其子项(如果有)(比解释更容易查看)。
输出(更新#1):
Array
(
[parentA] => Array
(
[child1] => Array
(
[child4] => Array
(
[child5] =>
)
)
[child2] =>
)
[parentB] => Array
(
[childC] =>
)
[parentC] => Array
(
[child3] =>
)
)
代码(更新#1):
<?php
$array = array(
array('parent' => 'parentA',
'name' => 'child1'),
array('parent' => 'parentB',
'name' => 'childC'),
array('parent' => 'parentA',
'name' => 'child2'),
array('parent' => 'parentC',
'name' => 'child3'),
array('parent' => 'child1',
'name' => 'child4'),
array( 'parent' => 'child4',
'name' => 'child5')
);
// parse array into a hierarchical tree structure
$tree = parseTree($array);
// Show results
echo '<pre>';
print_r($tree);
echo '</pre>';
echo "<br>Table Format:";
showresults($tree);
function parseTree(& $tree, $root = null) {
$return = null;
// Traverse the tree and search for children of current parent
foreach ($tree as $key=> $item){
// A child is found
if ($item['parent'] == $root){
// append child into array of children & recurse for children of children
$return[$item['name']] = parseTree($tree, $item['name']);
// delete child so won't include again
unset ($tree[$key]);
}
elseif ($root == null) {
// top level parent - add to array
$return[$item['parent']] = parseTree($tree, $item['parent']);
// delete child so won't include again
unset ($tree[$key]);
}
}
return $return;
}
function showresults($tree){
if (is_array($tree)){
echo "<table>";
echo "<tr>";
foreach ($tree as $key => $children){
echo "<tr>";
echo "<td style='border:1px solid'>";
echo $key;
echo "<td style='border:1px solid'>";
showresults($children, true);
echo "</td>";
echo "</td>";
echo "</tr>";
}
echo "</tr>";
echo "</table>";
}
}
?>