array_unique()去重后必须用array_values()重置索引,否则foreach遍历时因键不连续导致逻辑错乱;对二维数组无效,需按字段提取或序列化哈希去重;默认松散比较易误删不同语义值,应预处理类型或手动严格比较。

array_unique() 之后没重索引,导致 foreach 键错乱
常见现象是:用 array_unique() 去重后直接 foreach,结果遍历时跳过某些位置、或意外重复访问某项——因为 array_unique() 保留原始键名,返回数组像 [0 => 'a', 1 => 'b', 3 => 'c'],中间缺了键 2。foreach 按键遍历,不会自动补空,但逻辑上你以为是连续索引,实际不是。
- 必须加
array_values()重置索引:$clean = array_values(array_unique($arr)); - 如果依赖键做业务判断(比如“第几条记录”),不重索引会直接导致逻辑偏移
-
array_keys(array_flip($arr))虽快,但会丢失原始顺序(array_flip不保证键序),且不能处理非标量值
二维数组用 array_unique() 完全无效,还在原地循环
array_unique() 对含子数组的数组直接失效,内部把每个子数组转成字符串 "Array",所有行都“相同”,最终返回原数组。你看似在遍历去重后的结果,其实还是在遍历原始重复数据。
- 别对二维数组直接调
array_unique($arr2d),它不报错也不起效 - 按字段去重(如只看
id):先array_column($arr2d, 'id')提取,再array_unique(),最后用array_intersect_key($arr2d, array_flip($uniqueIds))还原 - 全量结构去重:用
serialize($item)生成哈希键,配合$seen数组查重,比in_array($item, $unique)快一个数量级
松散比较让 0、'0'、false 全被当成同一个值
默认 array_unique() 用松散比较(==),导致 0、'0'、false、'' 在去重时互相抵消。你删掉的可能不是重复项,而是语义完全不同的数据。
- PHP 8.2+ 可加
ARRAY_FILTER_USE_KEY?错,正确 flag 是SORT_REGULAR(默认)、SORT_STRING或SORT_NUMERIC;严格比较需手动预处理类型 - 要确保数值型去重:先
array_map('intval', $arr)再array_unique() - 要字符串精确匹配:统一转成字符串
array_map('strval', $arr),再用SORT_STRING(PHP 8.2+)或直接array_unique()(老版本默认就是字符串化比较)
用 in_array() 在循环里查重,大数据量直接卡死
写 foreach ($arr as $v) { if (!in_array($v, $unique)) $unique[] = $v; } 看似直观,但每次 in_array() 都是 O(n) 全扫描,整体变成 O(n²),10 万条数据可能耗时数秒。
- 换成哈希键查重:用
$key = is_scalar($v) ? $v : serialize($v)作键,isset($seen[$key])是 O(1) - 避免
json_encode()处理浮点数:0.1 + 0.2可能变成0.30000000000000004,序列化后哈希不一致;serialize()更稳定 - 内存敏感场景:超大数组别存完整
$seen,考虑分块或改用数据库/Redis 去重
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











