我需要通过使用单个数组中的group_parent_id
作为参考,将平面多维数组转换为层次结构。
令人烦恼的是,我只能使用用户有权访问的组的子集合,因此,虽然Test group
本身是孩子,但由于访问权限,它的父母实际上不在列表中。因此,从此用户角度来看,Test group
将被视为根级别
可悲的是,这属于递归,这不是我的强项...
输入:
$arr = [
[
'group_id' => 5,
'group_title' => 'Test group',
'group_parent_id' => 2
],
[
'group_id' => 6,
'group_title' => 'Second-level test group',
'group_parent_id' => 5
],
[
'group_id' => 7,
'group_title' => 'Third-level test group',
'group_parent_id' => 6
],
[
'group_id' => 8,
'group_title' => 'Other test group',
'group_parent_id' => 1
],
[
'group_id' => 9,
'group_title' => 'Second-level other test group',
'group_parent_id' => 8
]
];
所需的输出:
$arr = [
[
'group_id' => 5,
'group_title' => 'Test group',
'group_parent_id' => 2,
'subgroups' => [
[
'group_id' => 6,
'group_title' => 'Second-level test group',
'group_parent_id' => 5,
'subgroups' => [
[
[
'group_id' => 7,
'group_title' => 'Third-level test group',
'group_parent_id' => 6
]
]
]
]
]
],
[
'group_id' => 8,
'group_title' => 'Other test group',
'group_parent_id' => 1,
'subgroups' => [
[
'group_id' => 9,
'group_title' => 'Second-level other test group',
'group_parent_id' => 8
]
]
]
];
我尝试了一些不同的操作,但未能达到上述所需的期望结果:
function build_group_tree(array $groups, $group_ids = [])
{
$output = [];
foreach ($groups as $group) {
if (in_array($group['group_parent_id'], $group_ids)) {
$children = build_group_tree($groups, $group['group_id']);
if ($children) {
$group['subgroups'] = $children;
}
$output[] = $group;
}
}
return $output;
}
build_group_tree($arr, array_column($arr, 'group_id));
这给了我部分结果,但不包括所有组。
感谢任何帮助。
一种方法是遍历数组,在输出数组中创建对每个group_id
条目的引用列表,然后通过引用添加子项:
$output = array();
$group_ids = array();
foreach ($arr as $el) {
$parent_id = $el['group_parent_id'];
if (!isset($group_ids[$parent_id])) {
// must be a top-level element
$output[] = $el;
// save a pointer
$group_ids[$el['group_id']] = &$output[array_key_last($output)];
}
else {
// already exists, $group_ids[$parent_id] points to the entry
$parent = &$group_ids[$parent_id];
if (!isset($parent['subgroups'])) {
// no subgroups array, create one
$parent['subgroups'] = array();
}
// add this entry to the subgroups
$parent['subgroups'][] = $el;
// save a pointer
$group_ids[$el['group_id']] = &$parent['subgroups'][array_key_last($parent['subgroups'])];
}
}
print_r($output);
输出:
Array
(
[0] => Array
(
[group_id] => 5
[group_title] => Test group
[group_parent_id] => 2
[subgroups] => Array
(
[0] => Array
(
[group_id] => 6
[group_title] => Second-level test group
[group_parent_id] => 5
[subgroups] => Array
(
[0] => Array
(
[group_id] => 7
[group_title] => Third-level test group
[group_parent_id] => 6
)
)
)
)
)
[1] => Array
(
[group_id] => 8
[group_title] => Other test group
[group_parent_id] => 1
[subgroups] => Array
(
[0] => Array
(
[group_id] => 9
[group_title] => Second-level other test group
[group_parent_id] => 8
)
)
)
)
注意,此代码使用array_key_last
,它仅在7.3版中引入PHP。如果您使用的是较早版本,请使用array_key_last
代替。