如何将超过最大深度的子级数组(含对象)提升至父级列表?
数据
我有如下数据:
Array ( [0] => stdClass Object ( [tid] => 1 [t_name] => A [t_level] => 1 [children] => Array ( [0] => stdClass Object ( [tid] => 5 [t_name] => A.1 [t_level] => 2 ) [1] => stdClass Object ( [tid] => 6 [t_name] => A.2 [t_level] => 2 [children] => Array ( [0] => stdClass Object ( [tid] => 7 [t_name] => A.2.1 [t_level] => 3 [children] => Array ( [0] => stdClass Object ( [tid] => 9 [t_name] => A.2.1.1 [t_level] => 4 [array_val] => Array ( [0] => 0 [1] => 1 [2] => 2 ) [obj_val] => stdClass Object ( ) ) [1] => stdClass Object ( [tid] => 10 [t_name] => A.2.1.2 [t_level] => 4 ) ) ) [1] => stdClass Object ( [tid] => 8 [t_name] => A.2.2 [t_level] => 3 ) ) ) ) ) [1] => stdClass Object ( [tid] => 2 [t_name] => B [t_level] => 1 ) [2] => stdClass Object ( [tid] => 3 [t_name] => C [t_level] => 1 ) [3] => stdClass Object ( [tid] => 4 [t_name] => D [t_level] => 1 ) )
原始数据转换为JSON格式:
[{"tid":1,"t_name":"A","t_level":1,"children":[{"tid":5,"t_name":"A.1","t_level":2},{"tid":6,"t_name":"A.2","t_level":2,"children":[{"tid":7,"t_name":"A.2.1","t_level":3,"children":[{"tid":9,"t_name":"A.2.1.1","t_level":4,"array_val":[0,1,2],"obj_val":{}},{"tid":10,"t_name":"A.2.1.2","t_level":4}]},{"tid":8,"t_name":"A.2.2","t_level":3}]}]},{"tid":2,"t_name":"B","t_level":1},{"tid":3,"t_name":"C","t_level":1},{"tid":4,"t_name":"D","t_level":1}]
该数据深度为4,我希望将所有深度超过2的子级元素移动至层级为2的父级列表中。
预期结果
Array ( [0] => stdClass Object ( [tid] => 1 [t_name] => A [t_level] => 1 [children] => Array ( [0] => stdClass Object ( [tid] => 5 [t_name] => A.1 [t_level] => 2 ) [1] => stdClass Object ( [tid] => 6 [t_name] => A.2 [t_level] => 2 ) [2] => stdClass Object ( [tid] => 7 [t_name] => A.2.1 [t_level] => 2 ) [3] => stdClass Object ( [tid] => 9 [t_name] => A.2.1.1 [t_level] => 2 [array_val] => Array ( [0] => 0 [1] => 1 [2] => 2 ) [obj_val] => stdClass Object ( ) ) [4] => stdClass Object ( [tid] => 10 [t_name] => A.2.1.2 [t_level] => 2 ) [5] => stdClass Object ( [tid] => 8 [t_name] => A.2.2 [t_level] => 2 ) ) ) [1] => stdClass Object ( [tid] => 2 [t_name] => B [t_level] => 1 ) [2] => stdClass Object ( [tid] => 3 [t_name] => C [t_level] => 1 ) [3] => stdClass Object ( [tid] => 4 [t_name] => D [t_level] => 1 ) )
预期结果的JSON格式:
[{"tid":1,"t_name":"A","t_level":1,"children":[{"tid":5,"t_name":"A.1","t_level":2},{"tid":6,"t_name":"A.2","t_level":2},{"tid":7,"t_name":"A.2.1","t_level":2},{"tid":9,"t_name":"A.2.1.1","t_level":2,"array_val":[0,1,2],"obj_val":{}},{"tid":10,"t_name":"A.2.1.2","t_level":2},{"tid":8,"t_name":"A.2.2","t_level":2}]},{"tid":2,"t_name":"B","t_level":1},{"tid":3,"t_name":"C","t_level":1},{"tid":4,"t_name":"D","t_level":1}]
代码
我尝试了如下代码,但不知道如何将元素移动到父级,似乎没有方法可以设置父级值或追加到父级列表中:
$maxDepth = 2;// 允许的最大层级 $RAI = new \RecursiveArrayIterator($array); $RII = new \RecursiveIteratorIterator($RAI, \RecursiveIteratorIterator::SELF_FIRST); $RII->setMaxDepth($maxDepth); foreach ($RII as $key => $value) { if ($key === 't_level' && intval($value) > $maxDepth) { // 该怎么做?无法将它们移动到父级列表 } } unset($key, $value); $array = $RII->getArrayCopy(); // 查看结果 print_r($array);
解决方案
可以通过递归遍历的方式,收集所有层级超过2的元素并将其移动到层级2的父级列表中,同时修改元素的层级值:
function flattenToTargetLevel(&$items, $targetLevel = 2) { $result = []; foreach ($items as $item) { // 递归处理当前元素的子节点 if (isset($item->children) && is_array($item->children)) { // 扁平化子节点并合并到结果 $result = array_merge($result, flattenToTargetLevel($item->children, $targetLevel)); // 移除原元素的children属性 unset($item->children); } // 将超过目标层级的元素修改为目标层级 if ($item->t_level > $targetLevel) { $item->t_level = $targetLevel; } // 添加当前元素到结果列表 $result[] = $item; } return $result; } // 处理顶层的层级1元素 foreach ($array as &$topItem) { if (isset($topItem->children) && is_array($topItem->children)) { $topItem->children = flattenToTargetLevel($topItem->children); } } unset($topItem); // 输出处理后的结果 print_r($array);
代码说明
- 递归扁平化函数:
flattenToTargetLevel会遍历所有子元素,递归处理嵌套的children,将所有元素收集到同一层级,并修改元素的t_level为目标值(2)。 - 移除原嵌套结构:处理完成后会删除每个元素的
children属性,避免保留原嵌套关系。 - 修改顶层元素:遍历顶层的层级1元素,将其
children替换为扁平化后的列表,实现预期结构。
内容的提问来源于stack exchange,提问作者vee
相关产品推荐
相关产品推荐

