让我们马上挖掘主要问题,我有这样的输入
$category = array(
'A' => array('left' => 1, 'right' => 8),
'B' => array('left' => 2, 'right' => 3),
'C' => array('left' => 4, 'right' => 7),
'D' => array('left' => 5, 'right' => 6),
'E' => array('left' => 9, 'right' => 10),
);
我希望输出是这样的
$tree = array(
array('A', 'B'),
array('A', 'C', 'D'),
array('E'),
);
哪一个是通过输入数组循环并创建输出结果的最佳和快速函数?
答案 0 :(得分:16)
使用嵌套集是递归的理想选择。
鉴于您的数据:
$category = array(
'A' => array('left' => 1, 'right' => 9),
'B' => array('left' => 2, 'right' => 4),
'C' => array('left' => 5, 'right' => 8),
'D' => array('left' => 6, 'right' => 7),
'E' => array('left' => 10, 'right' => 11),
);
以下内容将您的嵌套集数据分解为PHP中正确嵌套的数组:
function createTree($category, $left = 0, $right = null) {
$tree = array();
foreach ($category as $cat => $range) {
if ($range['left'] == $left + 1 && (is_null($right) || $range['right'] < $right)) {
$tree[$cat] = createTree($category, $range['left'], $range['right']);
$left = $range['right'];
}
}
return $tree;
}
$tree = createTree($category);
print_r($tree);
输出:
Array
(
[A] => Array
(
[B] => Array
(
)
[C] => Array
(
[D] => Array
(
)
)
)
[E] => Array
(
)
)
然后,您可以使用以下内容将正确的树展平为所需的格式:
function flattenTree($tree, $parent_tree = array()) {
$out = array();
foreach ($tree as $key => $children) {
$new_tree = $parent_tree;
$new_tree[] = $key;
if (count($children)) {
$child_trees = flattenTree($children, $new_tree);
foreach ($child_trees as $tree) {
$out[] = $tree;
}
} else {
$out[] = $new_tree;
}
}
return $out;
}
$tree = flattenTree($tree);
print_r($tree);
输出:
Array
(
[0] => Array
(
[0] => A
[1] => B
)
[1] => Array
(
[0] => A
[1] => C
[2] => D
)
[2] => Array
(
[0] => E
)
)
答案 1 :(得分:0)
另一种解决方案,没有递归(请测试)
$result = array();
foreach($category as $key => $value) {
/*Get current row index*/
$i = count($result);
if($i == 0) {
$result[] = array($key);
} else {
$iParent = -1;
/*Find parent index*/
for($j = count($result[$i-1]) - 1; $j >= 0; $j--) {
if($value['left'] > $category[$result[$i-1][$j]]['left']
&& $value['right'] < $category[$result[$i-1][$j]]['right']) {
$iParent = $j;
break;
}
}
if($iParent == -1) { $result[] = array($key);}
if($iParent == count($result[$i-1]) - 1) {
// append to last
$result[$i-1][] = $key;
} else {
// make new list
$result[$i] = array_slice($result[$i-1], 0, $iParent + 1);
$result[$i][] = $key;
}
}
}
print_r($result);
答案 2 :(得分:0)
上述功能存在错误。删除@tree的第二个数组的顶级类别。这是修复:
foreach ($category as $name => $range) {
$line[$range['left']] = $name;
$line[$range['right']] = $name;
}
ksort($line);
$tree = array();
$count = 0;
foreach ($line as $name) {
if (!isset($open[$name])) {
$open[$name] = true;
$count++;
}
else {
if ($count > 0) {
$count = 0;
$tree[] = array_keys($open);
}
unset($open[$name]);
}
}
答案 3 :(得分:0)
我很少修改Stiven的代码。
public function createTree($category, $left = 0, $right = null) {
$tree = array();
foreach ($category as $cat => $range) {
if ($range['clf'] == $left + 1 && (is_null($right) || $range['crt'] < $right)) {
$tree[$cat]= array();
$tree[$cat]['title']=$range['title'];
if($range['crt']-$range['clf']>1){
$tree[$cat]['sub'] = $this->createTree($category, $range['clf'], $range['crt']);
}
$left = $range['crt'];
}
}
return $tree;
}
答案 4 :(得分:-1)
如果您不想使用递归:
foreach ($category as $name => $range) {
$line[$range['left']] = $name;
$line[$range['right']] = $name;
}
ksort($line);
$count = 0;
foreach($line as $name) {
if ( ! isset($open[$name])) {
$open[$name] = true;
$result[$name] = true;
$count++;
} else {
unset($open[$name]);
if ($count > 0) {
$count = 0;
$tree[] = array_keys($result);
$result = $open;
} else {
$result = array();
}
}
}