PHP如何将简单关联数组转换为指定拆分式数据结构
PHP 数组结构转换实现方案
明确转换规则
- 固定公共字段映射:原数组的两个基础字段统一替换为指定键名,值保持不变,所有生成的子数组都携带这两个公共字段
- 原
roles_id→ 新键user_roles_id - 原
assessments_id→ 新键hidden_courses_assessments_id
- 原
- 序号字段拆分逻辑:原数组中所有带数字后缀的序号字段(格式为
question_id_N、radio_id_N,N为数字序号),按N值两两归组,同序号的题、选项配对为一组,每组对应生成一个子数组条目- 组内的题ID字段,键名添加
hidden_前缀(即question_id_N→hidden_question_id_N) - 组内的选项ID字段(
radio_id_N)保留原键名和值
- 组内的题ID字段,键名添加
注:您提供的示例输出存在明显的键名笔误——按照“每两个序号字段为一组拆分”的规则,每个子数组仅包含公共字段+当前组的题、选项配对,不会混入其他序号的字段值,代码运行后生成的结构是匹配规则的正确结果。
实现代码
// 原始输入关联数组 $source = [ "roles_id" => "1", "assessments_id" => "1", "question_id_1" => "1", "radio_id_1" => "1", "question_id_2" => "2", "radio_id_2" => "5", "question_id_3" => "3", "radio_id_3" => "9" ]; // 提取公共字段并完成键名映射 $common = [ 'user_roles_id' => $source['roles_id'], 'hidden_courses_assessments_id' => $source['assessments_id'] ]; // 按序号归组所有序号化字段 $seqGroups = []; foreach ($source as $key => $val) { // 匹配 question_id_1、radio_id_2 这类带数字后缀的字段键 if (preg_match('/^(question_id|radio_id)_(\d+)$/', $key, $matchRes)) { $fieldType = $matchRes[1]; // 字段类型:question_id / radio_id $seqNo = $matchRes[2]; // 对应序号 $seqGroups[$seqNo][$fieldType] = $val; } } // 组装最终输出结构 $result = []; foreach ($seqGroups as $seqNo => $group) { $result[] = array_merge($common, [ "hidden_question_id_{$seqNo}" => $group['question_id'], "radio_id_{$seqNo}" => $group['radio_id'] ]); }
运行输出结果
上述代码执行后,会生成和规则匹配的结构化数据:
[ [ "user_roles_id" => "1", "hidden_courses_assessments_id" => "1", "hidden_question_id_1" => "1", "radio_id_1" => "1" ], [ "user_roles_id" => "1", "hidden_courses_assessments_id" => "1", "hidden_question_id_2" => "2", "radio_id_2" => "5" ], [ "user_roles_id" => "1", "hidden_courses_assessments_id" => "1", "hidden_question_id_3" => "3", "radio_id_3" => "9" ] ]
逻辑优化说明
- 采用正则动态匹配序号字段,无需硬编码序号值,原数组中新增N个问题组时无需修改代码,可自动识别归组
- 公共字段统一通过配置数组管理,后续调整映射关系时只需修改
$common数组的键值,避免重复写相同逻辑 - 基于序号值匹配分组,从根源上避免题和选项错配的问题
内容的提问来源于stack exchange,提问作者fabiobh
相关产品推荐
相关产品推荐

