如何将嵌套数组键作为前缀生成完整路径/地址字符串?
遍历未知深度嵌套数组生成完整路径字符串
我已经花了四天时间尝试解决这个问题,也做了谷歌搜索,但毫无进展。我的需求是遍历未知深度的嵌套数组,在遍历过程中保留上层键作为最终值的前缀,开启新路径时重置前缀,以此生成完整的地址字符串。
目标数组
$arr = [ "buildings" => [ "group1" => [ "b1" => [1,2,3,4], "b2" => [1,2,3] ], "group2" => [ "b1" => [1,2] ] ], "villas" =>[ "group1" => [ "v1" => [1,2], "v2" => [1] ], "group2" => [ "v1" => [1], "v2" => [1] ], "group3" => [ "v1" => [1] ], ] ];
期望输出
buildings/group1/b1/1 buildings/group1/b1/2 buildings/group1/b1/3 buildings/group1/b1/4 buildings/group1/b2/1 buildings/group1/b2/2 buildings/group1/b2/3 buildings/group2/b1/1 buildings/group2/b1/2 villas/group1/v1/1 villas/group1/v1/2 villas/group1/v2/1 villas/group2/v1/1 villas/group2/v2/1 villas/group3/v1/1
尝试的函数(未得到预期结果)
function test($array, $path = ""){ foreach ($array as $key => $value) { if (is_array($value)){ $path .= $key."/"; test($value, $path); } else { echo $path.$value."<br>"; } } } test($arr);
问题分析与解决方案
你当前的函数问题在于递归时修改了原$path变量,导致遍历兄弟节点时,路径会带上之前节点的键(比如遍历b1后,$path变成buildings/group1/b1/,再遍历b2时会在这个基础上拼接,得到错误的buildings/group1/b1/b2/)。
解决方法是不修改原$path,而是每次递归时传递拼接后的新路径,这样每个分支的路径都是独立的,不会互相干扰:
function test($array, $path = ""){ foreach ($array as $key => $value) { if (is_array($value)){ // 传递新的路径,不修改原$path test($value, $path . $key . "/"); } else { // 输出完整路径 echo $path . $value . "\n"; } } } test($arr);
原理说明
- 每次递归调用时,都会基于当前路径拼接当前键,生成新的路径字符串传递给下一层,原路径不会被修改。
- 当遍历到非数组的数值时,直接将当前路径与数值拼接输出,正好符合期望的格式。
内容的提问来源于stack exchange,提问作者M.M
相关产品推荐
相关产品推荐

