2 回答
TA贡献1712条经验 获得超3个赞
这将是一种方法:
<?php
$input = [
1 => [
'elementcount' => 3,
'parentcat' => 0,
'depth' => 1
],
4 => [
'elementcount' => 0,
'parentcat' => 1,
'depth' => 2
],
8 => [
'elementcount' => 0,
'parentcat' => 4,
'depth' => 3
],
9 => [
'elementcount' => 2,
'parentcat' => 4,
'depth' => 3
],
11 => [
'elementcount' => 3,
'parentcat' => 0,
'depth' => 1
],
12 => [
'elementcount' => 0,
'parentcat' => 11,
'depth' => 2
],
21 => [
'elementcount' => 3,
'parentcat' => 0,
'depth' => 1
]
];
$maxDepth = max(array_column($input, 'depth'));
// handle elements from higher to lower depth
for ($d = $maxDepth; $d >= 0; $d--) {
array_walk($input, function(&$entry, $index) use (&$input, $d) {
if (isset($entry['depth']) && $entry['depth'] == $d) {
// omit entries without elements or elements in children
if ($entry['elementcount'] < 1 && empty($entry['children'])) {
unset($input[$index]);
// handle as child entry of a parent entry
} else if (array_key_exists($entry['parentcat'], $input)) {
$input[$entry['parentcat']]['children'][$index] = [
'elementcount' => $entry['elementcount'],
'children' => isset($entry['children']) ? $entry['children'] : []
];
unset($input[$index]);
// handle as ordinary entry
} else {
$input[$index] = [
'elementcount' => $entry['elementcount'],
'children' => isset($entry['children']) ? $entry['children'] : []
];
}
}
});
}
print_r($input);
策略:
首先处理更高的深度,以便输入元素的顺序无关紧要
对于每个元素,检查父元素是否存在,如果存在,则将其填充在那里
重新定义所有处理的元素
明显的输出是:
(
[1] => Array
(
[elementcount] => 3
[children] => Array
(
[4] => Array
(
[elementcount] => 0
[children] => Array
(
[9] => Array
(
[elementcount] => 2
[children] => Array
(
)
)
)
)
)
)
[11] => Array
(
[elementcount] => 3
[children] => Array
(
)
)
[21] => Array
(
[elementcount] => 3
[children] => Array
(
)
)
)
与您的建议相比,我冒昧地创建了一个略有修改的结果:
'children' 属性始终作为数组存在。这使得结果的使用在以后更容易和更健壮。我想说的是,一般来说,如果可能的话,结构中的所有元素本身都应该具有相同的结构......
TA贡献1874条经验 获得超12个赞
function isParent($id, $list) : bool {
foreach($list as $item) {
if ($item['parentcat'] === $id) {
return true;
}
}
return false;
}
function buildLevel($parent, $catsByParent) : array {
$result = $catsByParent[$parent] ?? [];
foreach($result as $id => $cat) {
if (isset($catsByParent[$id])) {
$result[$id]['children'] = buildLevel($id, $catsByParent);
unset($catsByParent[$id]);
}
}
return $result;
}
// Filter out empty categories
$cats = array_filter(
$category_array,
function($cat, $id) use($category_array) {
return $cat['elementcount']>0 || isParent($id, $category_array);
},
ARRAY_FILTER_USE_BOTH
);
$catsByParent = [];
// Build cats list keyed by parentcat
foreach($cats as $id => $cat) {
$parent = $cat['parentcat'];
unset($cat['parentcat'], $cat['depth']);
$catsByParent[$parent] = ($catsByParent[$parent] ?? []) + [$id => $cat];
}
// Build result
$multidimensional_array = buildLevel(0, $catsByParent);
print_r($multidimensional_array);
第一个过滤掉空元素,即“其中没有元素或它们的任何子元素的类别”。(children 的 children 要求听起来很奇怪,那不就是再往下一层“他们的孩子”吗?)
然后剩余的类别由 parentcat 分组/排序,也就是“级别 id”,以使列表可行 :)。
然后遍历该列表,从顶部的级别 id 0 开始,并根据需要递归处理(子级)到最深处。
- 2 回答
- 0 关注
- 97 浏览
添加回答
举报