
本文介绍如何将含嵌套关联键值对的二维数组按键归组,合并相同键下的所有值并去重,最终生成以原键为索引、对应唯一值数组为元素的新结构。
本文介绍如何将含嵌套关联键值对的二维数组按键归组,合并相同键下的所有值并去重,最终生成以原键为索引、对应唯一值数组为元素的新结构。
在实际开发中(尤其处理 MySQL 中存储的 JSON 字段时),常遇到类似需求:多条记录的 option_sons 字段分别存有形如 {"2": "3", "3": "5"} 的 JSON 数据,需跨行聚合——将所有记录中键为 "2" 的值(如 "3"、"4")合并去重后归入 $result[2],键为 "3" 的值(如 "5"、"5")合并后仅保留一个 "5",最终得到结构清晰的分组唯一值数组。
实现该逻辑的核心在于双重遍历 + 键驱动归集 + 值去重。以下是完整、健壮的解决方案:
$result = [];
foreach ($item_options as $item_options_data) {
// 安全解码 JSON,避免因无效数据导致崩溃
$decoded = json_decode($item_options_data['option_sons'], true);
if (json_last_error() !== JSON_ERROR_NONE || !is_array($decoded)) {
continue; // 跳过解析失败或非数组数据
}
foreach ($decoded as $key => $value) {
// 确保目标键存在且为数值型或字符串型键(PHP 数组支持)
$normalizedKey = is_string($key) ? $key : (string)$key;
// 初始化子数组(若尚不存在)
if (!isset($result[$normalizedKey])) {
$result[$normalizedKey] = [];
}
// 追加当前值并自动去重(array_unique 保证值唯一性)
$result[$normalizedKey] = array_values(
array_unique(
array_merge($result[$normalizedKey], [$value])
)
);
}
}
// 输出结果(键保持原始类型,值为去重后的数字/字符串数组)
print_r($result);
✅ 关键要点说明:
- 键归集逻辑:外层遍历每条记录,内层遍历其 JSON 解析后的键值对;以 $key 作为 $result 的一级索引,天然实现“按键分组”。
- 去重与合并:使用 array_merge() 合并历史值与新值,再通过 array_unique() 消除重复项,最后用 array_values() 重置数组索引(确保输出为连续数字索引)。
- 健壮性增强:添加 json_decode() 错误检测,跳过非法 JSON,避免脚本中断;对键做字符串标准化处理,兼容数字键与字符串键。
- 性能提示:若数据量极大(如数千行),可考虑在数据库层预聚合(如用 JSON_TABLE + GROUP_CONCAT),PHP 层仅作最终去重。
最终输出示例:
Array (
[2] => Array( [0] => 3, [1] => 4 )
[3] => Array( [0] => 5 )
)
完全符合预期目标:每个原始 JSON 键成为顶层索引,其下值集合无重复、结构扁平、语义清晰。










