我有以下代码(我知道此代码未经过优化,但不适合讨论):
function select_categories($cat_id)
{
$this->db = ORM::factory('category')
->where('parent', '=', $cat_id)
->find_all();
foreach ($this->db as $num => $category)
{
if($category->parent == 0)
{
$this->tmp[$category->parent][$category->id] = array();
}
else {
$this->tmp[$category->parent][$category->id] = array();
}
$this->select_categories($category->id);
}
return $this->tmp;
}
函数返回此数组:
array(3) (
0 => array(2) (
1 => array(0)
2 => array(0)
)
2 => array(1) (
3 => array(0)
)
3 => array(2) (
4 => array(0)
5 => array(0)
)
)
但我应该如何更改代码
else {
$this->tmp[$category->parent][$category->id] = array();
// ^^^^^^^^^^^^^^^^^^^^^^ (this bit)
}
例如,要将array[3]
合并到array[2][3]
(因为array[3]
是array[2]
的子目录,而array[2]
是array[0][2]
的子目录)所以,我需要这样做(当我不知道子目录的级别时):
array (
0 => array (
1 => array
2 => array (
3 => array (
4 => array
5 => array
)
)
)
)
答案 0 :(得分:2)
很久以前我在PHP中写了一些代码来做这件事。它需要一个实体列表(在您的情况下,类别)并返回一个结构,其中这些实体排列在树中。但是,它使用关联数组而不是对象;它假定“父”ID存储在其中一个关联数组条目中。我相信你可以根据自己的需要调整它。
function make_tree_structure ($nontree, $parent_field)
{
$parent_to_children = array();
$root_elements = array();
foreach ($nontree as $id => $elem) {
if (array_key_exists ($elem[$parent_field], $nontree))
$parent_to_children [ $elem[$parent_field] ][] = $id;
else
$root_elements[] = $id;
}
$result = array();
while (count ($root_elements)) {
$id = array_shift ($root_elements);
$result [ $id ] = make_tree_structure_recurse ($id, $parent_to_children, $nontree);
}
return $result;
}
function make_tree_structure_recurse ($id, &$parent_to_children, &$nontree)
{
$ret = $nontree [ $id ];
if (array_key_exists ($id, $parent_to_children)) {
$list_of_children = $parent_to_children [ $id ];
unset ($parent_to_children[$id]);
while (count ($list_of_children)) {
$child = array_shift ($list_of_children);
$ret['children'][$child] = make_tree_structure_recurse ($child, $parent_to_children, $nontree);
}
}
return $ret;
}
要了解这是做什么的,首先尝试在这样的结构上运行它:
var $data = array (
0 => array('Name' => 'Kenny'),
1 => array('Name' => 'Lilo', 'Parent' => 0),
2 => array('Name' => 'Adrian', 'Parent' => 1)
3 => array('Name' => 'Mark', 'Parent' => 1)
);
var $tree = make_tree_structure($data, 'Parent');
如果我没弄错的话,你应该得到这样的东西: (“父”键仍然存在,但为了清楚起见我将其留下了) < /子>
array (
0 => array('Name' => 'Kenny', 'children' => array (
1 => array('Name' => 'Lilo', 'children' => array (
2 => array('Name' => 'Adrian')
3 => array('Name' => 'Mark')
)
)
)
检查代码以了解它是如何做到这一点的。一旦了解了它的工作原理,就可以调整它以处理特定数据。
答案 1 :(得分:1)
假设您不希望阵列中包含任何数据/子标记:
foreach ($this->db as $num => $category)
{
// save the data to the array
$this->tmp[$category->id] = array();
// save a reference to this item in the parent array
$this->tmp[$category->parent][$category->id] = &$this->tmp[$category->id];
$this->select_categories($category->id);
}
// the tree is at index $cat_id
return $this->tmp[$cat_id];
如果您只需要从数据库中检索完整的树,您甚至可以简化查询(一次获取所有记录)并删除此函数中的递归调用。如果不存在,您将需要额外的检查,只会设置$ this-&gt; tmp [$ catagory-&gt; id],否则它应该将数据与现有数据合并。