将带分隔符键路径的扁平关联数组转为多维关联数组
把扁平路径数组转换为带path/children的多维数组
这个需求我之前也碰到过,用循环+引用的方式就能完美解决,array_walk_recursive其实不太适合这里(它是用来遍历已有的多维数组的),而你说的用explode分割路径片段是核心思路,具体实现如下:
实现思路
- 初始化一个空的结果数组,用来存放最终的多维结构
- 遍历输入的每个键值对,把路径键按
/拆分成片段数组 - 用一个引用变量跟踪当前操作的数组层级,这样可以直接修改深层的数组节点
- 逐个处理路径片段:
- 如果是最后一个片段,给当前节点添加
path字段,赋值为对应的值 - 如果是中间片段,确保当前节点的
children存在(不存在就初始化),然后把引用指向这个children数组,继续处理下一个片段
- 如果是最后一个片段,给当前节点添加
PHP代码示例
$flatArray = [ 'projects' => 'A path', 'projects/project-a' => 'Another path', 'projects/project-b' => 'Yet another path', 'about/me/and/someone/else' => 'Path about me' ]; $result = []; foreach ($flatArray as $pathKey => $pathValue) { $segments = explode('/', $pathKey); $current = &$result; // 引用指向当前层级的数组 foreach ($segments as $index => $segment) { $isLast = ($index === count($segments) - 1); if ($isLast) { // 最后一个片段,添加path字段 $current[$segment]['path'] = $pathValue; } else { // 中间片段,确保children存在,然后移动引用到children if (!isset($current[$segment]['children'])) { $current[$segment]['children'] = []; } $current = &$current[$segment]['children']; } } unset($current); // 解除引用,避免后续循环污染 } print_r($result);
代码说明
- 引用的使用:
$current = &$result和后续的$current = &$current[$segment]['children']是关键,它让我们可以直接操作数组的深层节点,不需要每次重新遍历整个数组 - 区分片段类型:通过判断是否是最后一个片段,决定是添加
path还是处理children,完美适配你的需求(中间节点没有path,只有最后一个节点或单独的节点有path) - 未知深度支持:不管路径有多少层,循环都会逐个处理片段,自动构建对应的层级结构
运行这段代码后,得到的结果就和你期望的完全一致啦!
内容的提问来源于stack exchange,提问作者Jens Törnellt
相关产品推荐
相关产品推荐

