You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP递归练习:如何将JSON转为指定格式的关联数组

解决JSON转路径式键名关联数组的问题

首先,咱们先明确你的需求:把嵌套的JSON结构转换成以路径为键、对应值为值的扁平关联数组,同时你还想知道如何只保留关联索引对应的条目。我来一步步帮你修改递归函数,实现这两个需求。

一、修改递归函数构建目标数组

首先,你需要先把JSON字符串解码成PHP数组,然后通过递归遍历,维护当前的路径前缀,把每个标量值的完整路径作为键存入结果数组。这里关键是用引用传递来维护结果数组,避免每次递归重新创建数组。

完整代码示例:

<?php
$json_str = '{ "one": { "two": 3, "four": [ 5,6,7] }, "eight": { "nine": { "ten":11 } } }';
// 解码JSON为关联数组
$data = json_decode($json_str, true);

/**
 * 扁平化嵌套数组,生成路径式键名的关联数组
 * @param array $array 要处理的嵌套数组
 * @param string $prefix 当前路径前缀
 * @param array &$result 结果数组(引用传递)
 * @return array 扁平化后的数组
 */
function flattenArray($array, $prefix = '', &$result = []) {
    foreach ($array as $key => $value) {
        // 构建当前完整路径:前缀不为空时用"前缀/键",否则直接用键
        $currentPath = $prefix ? "{$prefix}/{$key}" : $key;
        
        if (is_array($value)) {
            // 如果是子数组,递归处理,把当前路径作为新前缀传入
            flattenArray($value, $currentPath, $result);
        } else {
            // 如果是标量值,把路径作为键、值作为值存入结果数组
            $result[$currentPath] = $value;
        }
    }
    return $result;
}

// 调用函数得到目标数组
$flattenedArray = flattenArray($data);
print_r($flattenedArray);
?>

运行这段代码后,你就能得到想要的结果:

Array
(
    [one/two] => 3
    [one/four/0] => 5
    [one/four/1] => 6
    [one/four/2] => 7
    [eight/nine/ten] => 11
)

二、仅获取关联索引对应的条目

如果想要排除索引数组(数字键的数组)中的元素,只保留来自关联数组的条目(比如上面例子中的one/two和eight/nine/ten),我们需要先判断数组是否为关联数组,再在递归中过滤掉索引数组的内容。

步骤1:编写关联数组判断函数

首先写一个工具函数,用来区分关联数组和索引数组:

/**
 * 判断是否为关联数组
 * @param array $array 要判断的数组
 * @return bool 是关联数组返回true,否则返回false
 */
function isAssocArray($array) {
    // 如果数组的键不是从0开始连续的数字,就是关联数组
    return is_array($array) && array_keys($array) !== range(0, count($array) - 1);
}

步骤2:修改递归函数过滤索引数组

基于之前的扁平化函数,修改成只处理关联数组的版本:

/**
 * 扁平化嵌套数组,仅保留关联索引对应的条目
 * @param array $array 要处理的嵌套数组
 * @param string $prefix 当前路径前缀
 * @param array &$result 结果数组(引用传递)
 * @return array 过滤后的扁平化数组
 */
function flattenAssocOnly($array, $prefix = '', &$result = []) {
    foreach ($array as $key => $value) {
        $currentPath = $prefix ? "{$prefix}/{$key}" : $key;
        
        if (is_array($value)) {
            // 只有当前数组是关联数组时,才递归处理子元素
            if (isAssocArray($value)) {
                flattenAssocOnly($value, $currentPath, $result);
            }
        } else {
            // 只有当前键不是数字(属于关联数组的键)时,才存入结果
            if (!is_numeric($key)) {
                $result[$currentPath] = $value;
            }
        }
    }
    return $result;
}

// 调用函数
$assocOnlyArray = flattenAssocOnly($data);
print_r($assocOnlyArray);

运行后得到的结果就是仅保留关联索引的条目:

Array
(
    [one/two] => 3
    [eight/nine/ten] => 11
)

补充说明

如果你的“关联索引”指的是其他逻辑(比如只保留特定前缀的路径),可以根据需求调整判断条件,比如在存入结果时检查路径是否符合特定规则即可。

内容的提问来源于stack exchange,提问作者ponytails_soda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:32:17