array_unique默认保留首次出现的元素,不识别业务时间顺序;需通过翻转数组或排序预处理来实现保留最新项。

array_unique 默认保留的是第一条,不是最新一条
array_unique() 的行为是硬编码的:它遍历数组时,**遇到重复值,只保留第一次出现的位置**,后续同值项全被丢弃。所以如果你的数组是按时间倒序(最新在前)或正序(最新在后)排列的,array_unique() 本身无法“智能选最新”——它只认顺序,不认业务含义。
想保留最新一条,得先反转再去重再反转
最直接、兼容性最好的做法是手动控制顺序:把数组翻转过来,让“最新”变成“最先”,用 array_unique() 去重,再翻回去。注意,这里必须用 array_reverse() 配合 $preserve_keys = true,否则键名会乱。
- 原始数组若为索引数组(数字键),可直接:
array_reverse(array_unique(array_reverse($arr))) - 若为关联数组(字符串键),且你依赖键名(比如
'user_id' => $data),必须显式传true:array_reverse(array_unique(array_reverse($arr, true)), true) - 如果原始键是时间戳或可排序字段,更稳妥的做法是先
uasort()排序,再array_unique(),避免靠翻转猜顺序
多维数组按某个字段去重(比如 'updated_at' 最新)
这时 array_unique() 完全失效,因为它只看整个子数组的 serialize() 结果,而两个结构相同但时间不同的数组仍被视为不同。你需要手动遍历:
- 先按目标字段(如
'updated_at')降序排序:usort($arr, fn($a, $b) => strtotime($b['updated_at']) strtotime($a['updated_at'])) - 再用一个临时哈希表记录已见过的唯一标识(如
$seen[$a['id']] = true),只保留首次命中该标识的元素 - 不要用
in_array()或array_search()做内层判断,复杂度会升到 O(n²),大数据量明显卡顿
SORT_STRING 或 SORT_NUMERIC 对“最新”没影响
第二个参数只改变值的比较方式(比如是否把 1 和 '1' 当作相同),**完全不干预保留哪一条的逻辑**。无论你传 SORT_STRING 还是 SORT_NUMERIC,array_unique() 永远只留第一次出现的那个——它不关心这个“第一次”是早还是晚,只认当前遍历顺序。
真正决定“最新”的,是你喂给它的数组顺序,以及你是否在去重前后做了翻转或排序。别指望函数自己理解业务时间线。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











