跳转到主内容
极星编程网:以代码为星,赴技术山海!

PHPJSON怎么去重_php清理json数组中重复项的方式【说明】

PHP中array_unique()不能直接处理JSON字符串,须先json_decode()转数组;对对象数组需按字段(如id)去重,可用array_column()+array_unique()+array_filter()或array_reduce()实现。 PHP 中用
array_unique()
处理 JSON 数组去重,但得先解码 JSON 字符串本身是纯文本,不能直接去重;必须先用
json_decode()
转成 PHP 数组,再操作。常见错误是试图对 JSON 字符串调用
array_unique()
,结果返回
null
或原样不变。 如果 JSON 是对象数组(如
[{"id":1},{"id":1}]
),
array_unique()
默认按「字符串值」比较,会失效——因为两个对象转字符串都是
Object
,判为相同 若 JSON 是简单一维数组(如
[1,2,2,3]
),
array_unique($arr)
可直接用,但注意它保留原始键名,需用
array_values()
重排索引 去重后别忘了用
json_encode()
转回 JSON,否则前端收不到合法格式 处理对象数组重复:用
array_column()
+
array_unique()
提取唯一标识 多数业务场景的“重复”其实指某个字段(如
id
、
email
)相同。直接对整个对象去重不可靠,应先抽取出关键字段做去重依据。 先
json_decode($json, true)
得到关联数组 用
array_column($arr, 'id')
提取所有
id
值,再
array_unique()
得唯一
id
列表 再用
array_filter()
遍历原数组,只保留
id
在唯一列表中首次出现的项(避免多次
in_array
低效) 示例片段:
$data = json_decode($json, true); $ids = array_column($data, 'id'); $unique_ids = array_unique($ids); $seen = []; $result = array_filter($data, function($item) use ($unique_ids, &$seen) { if (!in_array($item['id'], $unique_ids)) return false; if (isset($seen[$item['id']])) return false; $seen[$item['id']] = true; return true; });
用
array_reduce()
一行逻辑完成对象去重(PHP 7.4+ 更简洁) 比起多次遍历,用
array_reduce()
累积去重结果更高效,也更容易控制“保留第一个还是最后一个”。尤其适合字段不固定、需动态指定去重键的场景。 传入空数组作为初始值,每次检查当前项的去重键是否已存在,不存在则追加 注意:
array_reduce()
不保留原始键名,结果是数字索引数组,符合多数 API 返回预期 示例(按
name
去重):
$data = json_decode($json, true); $unique = array_reduce($data, function($carry, $item) { $key = $item['name'] ?? ''; if (!isset($carry[$key])) { $carry[$key] = $item; } return $carry; }, []); $result = array_values($unique); // 去掉关联键,只留数值索引
兼容性提示:PHP ?? 操作符 JSON 去重失败的三个典型错误信号 不是代码没跑,而是结果不对——这些现象说明去重逻辑或数据结构理解有偏差: PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。 下载 立即学习 “ PHP免费学习笔记(深入) ”;
json_decode()
返回
null
:检查 JSON 格式是否合法(用
json_last_error_msg()
查错),常见于中文乱码、尾部逗号、单引号代替双引号 去重后数组长度没变:大概率是对象数组被当字符串处理了,确认是否用了第二个参数
true
(否则返回对象,
array_unique()
无法处理) 部分重复项还在:检查去重字段是否存在空值、大小写差异(如
"Email"
和
"email"
)、前后空格(需提前
trim()
) 真正麻烦的不是语法,是搞不清“重复”的定义——是整行完全一样?还是某个字段一样?这个判断必须在写代码前就明确,否则后面全白调。

相关文章