array_unique 为什么对多维数组无效,如何自己实现多维数组去重

大萱小哥_7936

大萱小哥_7936

2026-10-06

730人浏览

原创

array_unique无法处理多维数组,因其内部将子数组转为字符串后均为"array",导致哈希冲突;需用serialize/json_encode标准化后再去重,或按指定键去重。

array_unique 为什么对多维数组无效,如何自己实现多维数组去重

array_unique 只能对一维数组去重,因为它内部比较的是元素的字符串值(或整数值),而多维数组的每个子数组在转换为字符串时都变成类似 Array 的固定字符串,导致所有子数组“看起来一样”,自然无法区分。

为什么 array_unique 处理不了多维数组

PHP 的 array_unique 底层使用哈希表去重,依赖 == 比较。但 PHP 中两个数组用 == 判断相等,需满足:键名相同、对应值相等且顺序一致。问题在于:array_unique 并不直接用 ==,而是把每个元素先 strval() 再哈希 —— 而任何数组转成字符串都是 "Array",所以所有子数组哈希后都撞到同一个桶里,只保留第一个。

例如:

$multi = [[1,2], [3,4], [1,2]]; var_dump(array_unique($multi)); // 输出仍是全部三个,没去重

手动实现多维数组去重(推荐:序列化 + 去重 + 反序列化)

核心思路:把每个子数组「标准化」为唯一可比的标量(如 JSON 字符串或序列化字符串),去重后再还原。

Day of AI
Day of AI

Day of AI是一款AI学习资源工具,麻省理工学院(MIT)推出的免费AI学习平台。

下载
  • 用 array_map('serialize', $arr) 把每个子数组转成唯一字符串
  • 用 array_unique 对这些字符串去重
  • 再用 array_map('unserialize', ...) 还原回数组

完整函数示例:

function array_unique_multi($arr) { if (!$arr) return $arr; $serialized = array_map('serialize', $arr); $unique_serialized = array_unique($serialized); return array_map('unserialize', $unique_serialized); }

更健壮的替代方案:用 JSON 编码(适合纯数值/字符串数据)

如果子数组不含资源、对象、闭包等不可 JSON 化的内容,用 json_encode 更安全(避免 unserialize 的潜在风险):

  • 编码时加 JSON_SORT_KEYS 和 JSON_NUMERIC_CHECK,确保结构等价的数组生成相同字符串
  • 注意:浮点数精度、null/0/'' 的类型差异可能影响结果,需按业务判断是否接受
function array_unique_multi_json($arr) { $jsons = array_map(function($item) { return json_encode($item, JSON_SORT_KEYS | JSON_NUMERIC_CHECK); }, $arr); $unique_jsons = array_unique($jsons); return array_map('json_decode', $unique_jsons); }

按指定键去重(关联多维数组常见需求)

比如用户数组 [ ['id'=>1,'name'=>'A'], ['id'=>2,'name'=>'B'], ['id'=>1,'name'=>'C'] ],想按 'id' 去重(保留首次出现):

  • 遍历原数组,用一个辅助数组记录已见过的 id
  • 遇到新 id 才加入结果,跳过重复项
function array_unique_by_key($arr, $key) { $seen = []; $result = []; foreach ($arr as $item) { if (is_array($item) && isset($item[$key]) && !in_array($item[$key], $seen)) { $seen[] = $item[$key]; $result[] = $item; } } return $result; }

不复杂但容易忽略细节。关键在选对“可比标识”——序列化保结构、JSON 保可读、键去重保业务语义。

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.20

2748

5

php中三维数组怎样求和
php中三维数组怎样求和

php中三维数组求和的方法:1、创建一个php示例文件;2、定义一个名为“$total”的变量,用于记录累加的结果。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

2299

5

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

2023.09.04

1118

7

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

2026.09.30

120

10

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

2026.09.30

100

14

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

2026.09.30

80

12

PDF转图片方法
PDF转图片方法

需要把 PDF 页面用于上传、预览、分享或图片归档时,PDF 转图片方法专题整理 JPG/PNG 格式选择、逐页导出、清晰度设置、批量下载和结果检查等流程,帮助用户稳定完成 PDF 图片化处理。

2026.09.30

60

26

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

2026.09.29

80

15

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

2026.09.23

280

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
php面试题实战视频教程
php面试题实战视频教程

共12课时 | 4.6万人学习