我有这个数组:
$arr = [
["id"=>20,
"name"=>"a",
"parent"=>28,
],
["id"=>21,
"name"=>"a-child",
"parent"=>20,
],
["id"=>27,
"name"=>"a-child-b",
"parent"=>20,
],
["id"=>28,
"name"=>"A parent",
"parent"=>0,
],
["id"=>12,
"name"=>"no parent",
"parent"=>0,
]];
我要基于parent
键对其进行分组,其中parent = id && parent > 0
或id
是该元素的父元素,并且如果父键更大,则该元素具有父元素大于零。
在上面的数组id=12
中没有父级,id=20
有子级21, 27
,它是id=28
的子级。
我做了什么:
public function sort($arr){
$result = [];
// Get child
foreach($arr as $key => $row) {
if($row['parent'] > 0) {
$result[$row->parent][] = ['id' => $row['id'], 'name' => $row['name']];
unset($arr[$key]);
}
}
// Get parent and append child
foreach($arr as $key => $row) {
$result[$row['id']] = ['name' => $row['name'],
'child' => $result[$row['id']]];
}
return $result;
}
问题是,这仅适用于parent => child array()
之类的1个孩子。
我想做的是一种获取参数(在数组上方)的方法,我不知道要进行多少层嵌套并按parent
键数组分组返回:
$arr = [
["id"=>28,
"name"=>"A parent",
"parent"=>0,
'child' => [
["id"=>20,
"name"=>"a",
"parent"=>28,
'child' => [
["id"=>21,
"name"=>"a-child",
"parent"=>20,
],
["id"=>27,
"name"=>"a-child-b",
"parent"=>20,
]
]
]
]
],
["id"=>12,
"name"=>"no parent",
"parent"=>0,
]];
答案 0 :(得分:2)
这是一种分两步的方法,首先构建将父对象映射到其子对象数组的关联数组,然后通过索引到父子关联数组来递归填充children
键。
请注意,我假设parent => 0
是根,但这也是可以调整的。我还使用了密钥children
,我觉得它更具有语义,但是可以随时还原为child
。
function insert(&$curr, $parents) {
if (array_key_exists($curr['id'], $parents)) {
$curr['children'] = $parents[$curr['id']];
}
if (array_key_exists('children', $curr)) {
foreach ($curr['children'] as &$child) {
insert($child, $parents);
}
}
}
function treeify($arr) {
foreach ($arr as $e) {
$parents[$e['parent']][] = $e;
}
foreach ($parents[0] as &$root) {
insert($root, $parents);
}
return $parents[0];
}
输出:
Array
(
[0] => Array
(
[id] => 28
[name] => A parent
[parent] => 0
[children] => Array
(
[0] => Array
(
[id] => 20
[name] => a
[parent] => 28
[children] => Array
(
[0] => Array
(
[id] => 21
[name] => a-child
[parent] => 20
)
[1] => Array
(
[id] => 27
[name] => a-child-b
[parent] => 20
)
)
)
)
)
[1] => Array
(
[id] => 12
[name] => no parent
[parent] => 0
)
)
答案 1 :(得分:2)
<?php
define('ROOT_PARENT',0);
function getHierarchy($records){
$hierarchy = [];
/*
let's assume everybody is going to be a parent
*/
foreach($records as $each_record){
$each_record['child'] = [];
$hierarchy[$each_record['id']] = $each_record;
}
/*
Now add child to parent's key in $hierarchy in the 'child' key.
The & is important since there may be future childs for current child. So pass by reference is needed
*/
foreach($records as $each_record){
$hierarchy[$each_record['parent']]['child'][] = &$hierarchy[$each_record['id']];
}
/*
here I unset every key which wasn't at root level,i.e is 0(top) level
*/
foreach($hierarchy as $parent => $its_data){
if($parent != ROOT_PARENT){
unset($hierarchy[$parent]);
}
}
return isset($hierarchy[ROOT_PARENT],$hierarchy[ROOT_PARENT]['child']) ? $hierarchy[ROOT_PARENT]['child'] : [];
}
$records = [
[
"id" => 20,
"name" => "a",
"parent" => 28,
],
[
"id" => 21,
"name" => "a-child",
"parent" => 20,
],
[
"id" => 27,
"name" => "a-child-b",
"parent" => 20,
],
[
"id" => 28,
"name" => "A parent",
"parent" => 0,
],
[
"id" => 12,
"name" => "no parent",
"parent" => 0,
]
];
echo "<pre>";
print_r(getHierarchy($records));
输出:
Array
(
[0] => Array
(
[id] => 28
[name] => A parent
[parent] => 0
[child] => Array
(
[0] => Array
(
[id] => 20
[name] => a
[parent] => 28
[child] => Array
(
[0] => Array
(
[id] => 21
[name] => a-child
[parent] => 20
[child] => Array
(
)
)
[1] => Array
(
[id] => 27
[name] => a-child-b
[parent] => 20
[child] => Array
(
)
)
)
)
)
)
[1] => Array
(
[id] => 12
[name] => no parent
[parent] => 0
[child] => Array
(
)
)
)
首先,我们认为每个人都可以成为父母。然后,在它的父级child
键中,我们继续添加它的子级。我们通过参考传递key
,因为将来可能会有孩子。最后,unset()
来自层次结构的不是根父级的每个人。最后,您将拥有最终的层次结构。