php按id字段去重最简方法非array_column()+array_unique(),因其仅保留最后id元素;稳定做法是遍历+isset($seen[$item['id']])映射,o(1)查重、保留首个出现项,且避免in_array()的o(n)开销。

PHP数组按id字段去重的最简方法
直接用array_column() + array_unique()组合,但要注意:这只能保留最后一个重复id的元素,不是默认去重逻辑。真正稳定可控的做法是手写遍历+键映射。
- 先用
$seen = []记录已出现过的id值 - 遍历原数组,对每个元素检查
$item['id']是否在$seen中 - 没出现过就追加到结果数组,并把
$item['id']写入$seen
$unique = [];
$seen = [];
foreach ($data as $item) {
if (!isset($seen[$item['id']])) {
$seen[$item['id']] = true;
$unique[] = $item;
}
}
为什么array_unique($arr, SORT_REGULAR)不适用
这个函数比较的是整个子数组的结构和值,不是单个字段。哪怕两个元素id相同但其他字段不同,它也不会认为重复;反之,如果两个元素完全一样(包括id和其他字段),它才去重——这不是你想要的“按id去重”。
- 错误预期:
array_unique($data, SORT_REGULAR)能筛掉id=5的重复项 → 实际不会 - 它只对纯数值/字符串数组或完全一致的关联数组生效
- PHP 8.1+ 仍无内置字段级去重函数,必须手动控制
处理对象数组时别直接用$obj->id当数组键
对象属性不能直接作数组下标(会触发Notice: Object of class X could not be converted to string),得先转成可哈希的值。
- 安全做法:
$key = (string) $obj->id或$key = $obj->id . '' - 如果
id可能为null或对象,用spl_object_id($obj)不解决问题——你要的是业务id去重,不是对象实例去重 - 更稳妥:
$key = is_scalar($obj->id) ? (string) $obj->id : md5((string) $obj->id)
大数据量时性能差异明显
用isset($seen[$id])查键是O(1),而用in_array($id, $ids)是O(n),10万条数据后者可能慢100倍以上。
- 千万别说“先
array_column($data, 'id')再array_flip”,那会多一次全量遍历 - 也别在循环里反复调用
array_search()找id位置,开销更大 - 如果原始数据来自数据库,优先考虑在SQL层用
GROUP BY id或DISTINCT ON (id)(PostgreSQL)
真正容易被忽略的是:去重逻辑是否要保留第一个出现的元素?上面示例保留的是第一个;若要保留最后一个,就把if (!isset(...))改成覆盖赋值即可——这点常被当成理所当然,但业务语义往往要求明确指定。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











