
本文详解如何将原始 json 中分散的水果数据、总量及多维度尺寸关联项,重组为按水果聚合、尺寸有序排列的新数组结构,适用于表格渲染等场景。
在实际开发中,后端返回的 jsON 数据常以扁平化或分块形式组织(如 fruits、size、SizeAndFruit 三个独立数组),但前端展示(如数据表格、图表)往往需要按主体(例:水果)聚合,并保留关联维度(例:不同规模人群下的销量)且严格排序。本文提供一套完整、可复用的 php 解决方案,实现从原始响应到目标结构 {“newArray”: […]} 的精准转换。
核心思路
- 初始化基础骨架:遍历 fruits 数组,为每种水果创建初始对象,包含 name 和 totalResults(即总件数);
- 填充关联明细:遍历 SizeAndFruit,将每个条目(含 size、pieces、name)归入对应水果的 sortedResults 子数组;
- 按业务逻辑排序:因 size 字段为字符串(如 “100-500 eaters”),需映射为数值优先级,再使用 usort() 确保 “100-500 eaters” → “5000-10,000 eaters” → “10,001+ eaters” 的升序排列。
完整实现代码
fruits as $fruit) { $out[] = [ 'name' => $fruit->name, 'totalResults' => $fruit->pieces, 'sortedResults' => [], ]; } // 步骤2:将 SizeAndFruit 条目归类到对应水果 foreach ($inputJson->SizeAndFruit as $entry) { $newEntry = [ 'size' => $entry->size, 'pieces' => $entry->pieces, ]; // 查找匹配的水果并追加 foreach ($out as &$fruit) { if ($fruit['name'] === $entry->name) { $fruit['sortedResults'][] = $newEntry; break; // 找到即退出,提升效率 } } } // 步骤3:定义 size 字符串到排序权重的映射 function sizeStringToNumber(string $size): int { $mapping = [ '100-500 eaters' => 100, '5000-10,000 eaters' => 5000, '10,001+ eaters' => 10001, ]; return $mapping[$size] ?? 99999; // 未知值置后 } // 对每个水果的 sortedResults 按 size 权重升序排序 foreach ($out as &$fruit) { usort($fruit['sortedResults'], function ($a, $b) { return sizeStringToNumber($a['size']) <=> sizeStringToNumber($b['size']); }); } // 组装最终输出 $result = [ 'newArray' => $out, ]; // 输出格式化 json(便于调试与前端消费) echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
关键注意事项
- ✅ 性能优化:内层循环使用 break 避免冗余遍历;若数据量极大(>10k 条),建议预先构建水果名称索引(如 [‘Bananas‘ => 0, ‘Oranges’ => 1])实现 O(1) 查找;
- ✅ 健壮性:sizeStringToNumber() 函数包含兜底逻辑,防止未知 size 值导致排序异常;
- ✅ 扩展性:排序规则完全由 $mapping 数组控制,新增尺寸类型只需扩展映射表,无需修改排序逻辑;
- ⚠️ JSON 解析安全:生产环境务必检查 json_last_error(),避免无效 JSON 导致脚本中断;
- ⚠️ 内存考虑:对于超大响应,可改用流式解析(如 json_decode 配合 JSON_BIGINT_AS_STRING)或分批处理。
该方案不仅满足当前需求,其模块化设计(初始化 → 归类 → 排序 → 输出)也易于适配其他类似聚合场景,例如按地区+产品、按季度+渠道等多维交叉分析结构的构建。