我继承了一个我从未见过父/子树的表结构。这不是阵列问题的典型父/子树。
它涉及3个阵列;公司,部门,用户
少数规则
我尝试过的事情
我疯狂地搜索,看看是否有其他人不得不做类似的事情并且什么都没发现。我从公司数组开始,走了一个递归函数和引用方法的道路。但是,一旦我需要开始将公司或部门作为孩子加入,然后检查该部门是否有任何子公司或部门,我就完全迷失了如何使其进入任何深度。
最终结果我正在寻找
这个数组结构。的 Look a this picture for the full structure.
Array
(
[company_799] => Array
(
[companyid] => 799
[parent_companyid] => 0
[parent_divisionid] => 0
[companyname] => Main Company
[children] => Array
(
[user_3138] => Array
(
[userid] => 3138
[companyid] => 799
[company_divisionid] =>
[username] => test user 1
)
[division_58] => Array
(
[divisionid] => 58
[parent_companyid] => 799
[parent_divisionid] => 0
[division_name] => Division 1
[children] => Array
(
[user_3139] => Array
.. etc...
公司数组
Array
(
[799] => Array
(
[companyid] => 799
[parent_companyid] => 0
[parent_divisionid] => 0
[companyname] => Main Company
)
[800] => Array
(
[companyid] => 800
[parent_companyid] => 799
[parent_divisionid] => 0
[companyname] => Sub Company 1
)
[801] => Array
(
[companyid] => 801
[parent_companyid] => 800
[parent_divisionid] => 0
[companyname] => Sub Company 2
)
[802] => Array
(
[companyid] => 802
[parent_companyid] => 0
[parent_divisionid] => 59
[companyname] => Sub Company of Division
)
)
司
Array
(
[58] => Array
(
[divisionid] => 58
[parent_companyid] => 799
[parent_divisionid] => 0
[division_name] => Division 1
)
[60] => Array
(
[divisionid] => 60
[parent_companyid] => 801
[parent_divisionid] => 0
[division_name] => Sub Division of Company
)
[59] => Array
(
[divisionid] => 59
[parent_companyid] => 0
[parent_divisionid] => 58
[division_name] => Sub Division of division
)
)
用户
Array
(
[3138] => Array
(
[userid] => 3138
[companyid] => 799
[parent_divisionid] => 0
[username] => test user 1
)
[3139] => Array
(
[userid] => 3139
[companyid] => 799
[parent_divisionid] => 58
[username] => test user 2
)
[3140] => Array
(
[userid] => 3140
[companyid] => 799
[parent_divisionid] => 59
[username] => test user 3
)
[3141] => Array
(
[userid] => 3141
[companyid] => 802
[parent_divisionid] => 0
[username] => test user 4
)
[3142] => Array
(
[userid] => 3142
[companyid] => 800
[parent_divisionid] => 0
[username] => test user 5
)
)
答案 0 :(得分:1)
这是我提出的解决方案。不是最优雅,但它的工作原理。谢谢RST的帮助。
build_tree()在函数的第一次传递中基本构建了树。在函数结束时,如果公司/部门/用户数组中仍有数据,它将以递归方式调用自身。
public function get_tree()
{
$arr_treedata = array();
$arr_treedata['tree'] = array(); // Where the final tree will be stored
$arr_treedata['companies'] = $this->get_companies(); // From mysql table
$arr_treedata['divisions'] = $this->get_divisions(); // From mysql table
$arr_treedata['users'] = $this->get_users(); // From mysql table
return $this->build_tree($arr_treedata);
}
private function build_tree($arr_treedata)
{
// Append company nodes
if (count($arr_treedata['companies']) > 0)
{
foreach ($arr_treedata['companies'] as $str_companyid => $arr_company)
{
$str_search_key = FALSE;
if ($arr_company['parent_companyid'] == 0 && $arr_company['parent_divisionid'] == 0)
{
// Root node found
$arr_treedata['tree'][$str_companyid] = $arr_company;
unset($arr_treedata['companies'][$str_companyid]);
}
else if ($arr_company['parent_companyid'] > 0 && $arr_company['parent_divisionid'] == 0)
{
// Company is a child of a company
$str_search_key = 'company_'.$arr_company['parent_companyid'];
}
else if ($arr_company['parent_companyid'] == 0 && $arr_company['parent_divisionid'] > 0)
{
// Company is a child of a division
$str_search_key = 'division_'.$arr_company['parent_divisionid'];
}
if ($str_search_key !== FALSE)
{
// Search for the key
$arr_insertdata = array('children' => array($str_companyid => $arr_company));
$arr_newtreedata = $this->search_tree_and_insert($arr_treedata['tree'], $str_search_key, $arr_insertdata);
if ($arr_treedata['tree'] != $arr_newtreedata)
{
// Key found and new tree data detected
$arr_treedata['tree'] = $arr_newtreedata;
unset($arr_treedata['companies'][$str_companyid]);
}
}
}
}
// Append division nodes
if (count($arr_treedata['divisions']) > 0)
{
foreach ($arr_treedata['divisions'] as $str_divisionid => $arr_division)
{
$str_search_key = FALSE;
if ($arr_division['parent_companyid'] != '' && $arr_division['parent_divisionid'] == '')
{
// Division is a child of a company
$str_search_key = 'company_'.$arr_division['parent_companyid'];
}
else if ($arr_division['parent_companyid'] != '' && $arr_division['parent_divisionid'] != '')
{
// Division if a child of a division
$str_search_key = 'division_'.$arr_division['parent_divisionid'];
}
if ($str_search_key !== FALSE)
{
// Search for the key
$arr_insertdata = array('children' => array($str_divisionid => $arr_division));
$arr_newtreedata = $this->search_tree_and_insert($arr_treedata['tree'], $str_search_key, $arr_insertdata);
if ($arr_treedata['tree'] != $arr_newtreedata)
{
// Key found and new tree data detected
$arr_treedata['tree'] = $arr_newtreedata;
unset($arr_treedata['divisions'][$str_divisionid]);
}
}
}
}
// Append user nodes
if (count($arr_treedata['users']) > 0)
{
foreach ($arr_treedata['users'] as $str_userid => $arr_user)
{
$str_search_key = FALSE;
if ($arr_user['parent_companyid'] != '' && $arr_user['parent_divisionid'] == '')
{
// User is a child of a company
$str_search_key = 'company_'.$arr_user['parent_companyid'];
}
else if ($arr_user['parent_companyid'] != '' && $arr_user['parent_divisionid'] != '')
{
// User if a child of a division
$str_search_key = 'division_'.$arr_user['parent_divisionid'];
}
if ($str_search_key !== FALSE)
{
// Search for the key
$arr_insertdata = array('children' => array($str_userid => $arr_user));
$arr_newtreedata = $this->search_tree_and_insert($arr_treedata['tree'], $str_search_key, $arr_insertdata);
if ($arr_treedata['tree'] != $arr_newtreedata)
{
// Key found and new tree data detected
$arr_treedata['tree'] = $arr_newtreedata;
unset($arr_treedata['users'][$str_userid]);
}
}
}
}
if (count($arr_treedata['divisions']) > 0 || count($arr_treedata['companies']) > 0 || count($arr_treedata['users']) > 0)
{
$arr_treedata = $this->build_tree($arr_treedata);
}
return $arr_treedata;
}
// Search the tree for an array key and merge the data
private function search_tree_and_insert($arr_treedata, $str_search_key, $arr_insertdata)
{
foreach ($arr_treedata as $str_keyid => $arr_row)
{
if ($str_keyid == $str_search_key)
{
// Found key, merge in the provided data
$arr_treedata[$str_keyid] = array_merge_recursive($arr_treedata[$str_keyid], $arr_insertdata);
}
else if (isset($arr_row['children']))
{
// Search Children
$arr_treedata[$str_keyid]['children'] = $this->search_tree_and_insert($arr_row['children'], $str_search_key, $arr_insertdata);
}
}
return $arr_treedata;
}
<强>结果强>
[company_799] => Array
(
[companyid] => 799
[parent_companyid] => 0
[parent_divisionid] => 0
[companyname] => Main Company
[children] => Array
(
[company_800] => Array
(
[companyid] => 800
[parent_companyid] => 799
[parent_divisionid] => 0
[companyname] => Sub Company 1
[children] => Array
(
[company_801] => Array
(
[companyid] => 801
[parent_companyid] => 800
[parent_divisionid] => 0
[companyname] => Sub Company 2
[children] => Array
(
[division_60] => Array
(
[divisionid] => 60
[parent_companyid] => 801
[parent_divisionid] =>
[division_name] => Sub Division of Company
)
)
)
)
)
[division_58] => Array
(
[divisionid] => 58
[parent_companyid] => 799
[parent_divisionid] =>
[division_name] => Division 1
[children] => Array
(
[division_59] => Array
(
[divisionid] => 59
[parent_companyid] => 799
[parent_divisionid] => 58
[division_name] => Sub Division of division
[children] => Array
(
[user_3140] => Array
(
[userid] => 3140
[parent_companyid] => 799
[parent_divisionid] => 59
[username] => test user 3
)
[company_802] => Array
(
[companyid] => 802
[parent_companyid] => 0
[parent_divisionid] => 59
[companyname] => Sub Company of Division
)
)
)
[user_3139] => Array
(
[userid] => 3139
[parent_companyid] => 799
[parent_divisionid] => 58
[username] => test user 2
)
)
)
)
)
答案 1 :(得分:1)
这就是我的意思。我会改变两件事,但那只是我。
从客户开始,因为他们的父母已经在分部或公司中。然后处理分歧,因为他们的父母也已经出现在公司中,如果没有,那么这个部门可以作为父母加入。
以这种方式处理它会删除你正在进行的大量搜索,你可以检查数组索引以查看父项是否存在。
我不太喜欢if, elseif, elseif
结构。我会把它改成
if ( ! empty($arr_company['parent_companyid'] ) {
// add to company
// other actions
continue;
}
if ( ! empty($arr_company['parent_divisionid'] ) {
// add to division
//other actions
continue;
}
// no company or division parent id
// add to tree as new division/company