数组怎么去重_PHP数组去重函数使用【操作】

2次阅读

Array_unique() 是 php 一维数组去重的标准方法,但不支持多维数组;二维数组需按唯一字段(如 id)手动去重,或序列化哈希;PHP 8.3 新增严格模式 flag,注意版本兼容性。

数组怎么去重_PHP数组去重函数使用【操作】

array_unique() 是 PHP 数组去重的唯一标准解法

它能直接处理一维数组,对值去重并保留首次出现的键名。但注意:array_unique() 不会改变原数组,必须重新赋值;而且它只比较「值」,不递归处理多维数组。

常见错误是以为它能去重二维数组或对象数组——实际会报 Array to String conversion 警告,因为内部尝试把数组转成字符串做哈希比对。

  • 字符串、数字混排时,"1"1 默认会被视为相同(松散比较),加 SORT_REGULAR 可避免
  • 关联数组去重后键名保留,但顺序可能打乱(底层用哈希表实现)
  • 大数据量时性能尚可,但比纯索引数组慢约 20%~30%,因要维护键值映射

二维数组去重得自己写逻辑,别硬套 array_unique()

比如你有一组用户数据:[["id"=>1,"name"=>"a"],["id"=>2,"name"=>"b"],["id"=>1,"name"=>"a"]],想按 id 去重。这时 array_unique() 完全无效。

最稳妥的做法是用 foreach + isset() 检查已存在键:

立即学习PHP免费学习笔记(深入)”;

$unique = []; foreach ($data as $item) {     if (!isset($unique[$item['id']])) {         $unique[$item['id']] = $item;     } }

注意:这种写法依赖某个唯一字段(如 id),如果没现成唯一键,就得用 serialize($item) 当哈希值,但要注意序列化开销和浮点数精度问题。

  • array_column() 提取某列再配合 array_unique() 只能拿到去重后的值,丢键又丢整行数据
  • array_filter() 配合闭包也能做,但可读性差、性能略低,不推荐日常用
  • PHP 8.1+ 的 array_key_first() 在某些遍历场景有用,但和去重无直接关系

去重后想重排键名?用 array_values() 就行

array_unique() 返回的数组键名是稀疏的(比如原数组键为 0,2,5,去重后还是这样)。如果后续要 json_encode() 或传给前端,常需要连续数字键。

直接包一层 array_values() 即可:

$clean = array_values(array_unique($arr));

但注意:这会丢失所有原始键名信息。如果你靠键名存业务含义(比如配置项名),就不能这么干。

  • array_values() 是 O(n) 操作,几乎无性能负担
  • 它不改变值本身,只重置键,和 array_unique() 组合是安全的
  • 别误用 array_merge([]...) 来重排键——虽然效果一样,但语义不清且多一次函数调用

PHP 8.3 的 array_unique() 新增 flags 参数容易被忽略

新版支持 ARRAY_UNIQUE_STRICTARRAY_UNIQUE_LOOSE,显式控制类型比较方式。以前只能靠第三个参数传 SORT_STRING 等间接影响,现在更直白。

例如严格模式下,"1"1 不再被当成重复项:

array_unique([1, "1", 2], ARRAY_UNIQUE_STRICT); // 返回 [1, "1", 2]

但要注意:这个 flag 在 PHP 8.3 才引入,线上环境低于该版本会 fatal Error。检查版本不能只看 PHP_VERSION_ID,还得确认是否启用了新特性开关(某些 docker 镜像默认关)。

  • 升级前务必在测试环境验证旧代码行为是否变化
  • CI 中加 php -vphp -r "var_dump(defined('ARRAY_UNIQUE_STRICT'));" 双重校验
  • 框架封装的“通用去重工具函数”如果没适配此 flag,很可能悄悄失效

实际用的时候,先盯死你的数组维度和数据类型,再选函数还是手写;二维数组去重没有银弹,靠字段唯一性做索引是最稳的路子。

text=ZqhQzanResources