具有 ID 的父子树分布在多个 arrays/tables
Parent child tree with ID's spread through multiple arrays/tables
我继承了一个 table 结构,这是我从未见过的 parent/child 树。这不是典型的 parent/child 树到数组的问题。
涉及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
)
)
这是我想到的解决方案。不是最优雅的,但它确实有效。感谢 RST 的帮助。
build_tree() 基本上是在函数的第一遍构建树。函数结束时,如果company/divisions/users数组中还有数据,则递归调用自身
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
)
)
)
)
)
这就是我的意思。我会改变两件事,但那只是我。
从客户开始,因为他们 parent 已经存在,无论是在部门还是在公司。然后处理部门,因为他们的 parent 也已经存在于公司中,如果没有,则可以将此部门添加为 parent.
以这种方式处理它会减少您正在进行的大量搜索,您可以只检查数组索引以查看是否存在 parent。
我不太喜欢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
我继承了一个 table 结构,这是我从未见过的 parent/child 树。这不是典型的 parent/child 树到数组的问题。
涉及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
)
)
这是我想到的解决方案。不是最优雅的,但它确实有效。感谢 RST 的帮助。
build_tree() 基本上是在函数的第一遍构建树。函数结束时,如果company/divisions/users数组中还有数据,则递归调用自身
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
)
)
)
)
)
这就是我的意思。我会改变两件事,但那只是我。
从客户开始,因为他们 parent 已经存在,无论是在部门还是在公司。然后处理部门,因为他们的 parent 也已经存在于公司中,如果没有,则可以将此部门添加为 parent.
以这种方式处理它会减少您正在进行的大量搜索,您可以只检查数组索引以查看是否存在 parent。
我不太喜欢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