PHP中如何去除多维数组中的重复元素?
去除多维数组重复元素的高效方案
嘿,这个问题我太熟了!要搞定多维数组的去重,核心难点在于普通的去重方法(比如Set)没法直接识别内容相同的子数组——毕竟数组是引用类型,哪怕内容一模一样,只要内存地址不同,就会被当成不同元素。结合你给出的场景(第三个、第五个元素和第零个完全相同被移除),下面给你几种实用且高效的解决方案:
方案1:JSON序列化 + Set(简洁首选)
如果你的多维数组里都是普通可序列化的值(数字、字符串、普通对象这类),这个方法绝对是最省心的:
// 示例原数组 const arrBefore = [[1,2,3], [4,5,6], [1,2,3], [7,8,9], [1,2,3]]; // 去重逻辑 const arrAfter = Array.from( new Set(arrBefore.map(item => JSON.stringify(item))) ).map(str => JSON.parse(str)); console.log(arrAfter); // 输出: [[1,2,3], [4,5,6], [7,8,9]]
原理说明:
把每个子数组转成JSON字符串后,内容相同的数组会变成完全一致的字符串,这时用Set就能轻松去重,最后再把字符串转回数组即可。
优缺点:
- ✅ 代码极简,容易理解和实现
- ❌ 无法处理不可JSON序列化的元素(比如函数、
undefined、Symbol)
方案2:自定义比较函数 + 过滤(灵活适配复杂场景)
如果你的数组里有特殊类型,或者需要自定义“相等”的规则(比如忽略某些嵌套字段),可以写一个数组相等的辅助函数,再结合filter去重:
const arrBefore = [[1,2,3], [4,5,6], [1,2,3], [7,8,9], [1,2,3]]; // 辅助函数:递归判断两个数组是否完全相等 function arraysEqual(a, b) { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { // 嵌套数组的话递归判断,否则直接比较值 if (Array.isArray(a[i]) && Array.isArray(b[i])) { if (!arraysEqual(a[i], b[i])) return false; } else if (a[i] !== b[i]) { return false; } } return true; } // 去重逻辑:只保留第一个出现的元素 const arrAfter = arrBefore.filter((item, index, self) => { return self.findIndex(el => arraysEqual(el, item)) === index; }); console.log(arrAfter); // 输出目标数组
原理说明:
findIndex会返回第一个和当前元素匹配的索引,只有当当前元素的索引等于这个值时,才保留它——相当于只留每个重复组的第一个元素。
优缺点:
- ✅ 支持嵌套多维数组,可自定义相等逻辑
- ❌ 时间复杂度是O(n²),数组特别大时性能会受影响
方案3:Map优化(大数据量首选)
如果你的数组元素数量很多,方案2的O(n²)性能不够看,可以用Map把时间复杂度降到O(n):
const arrBefore = [[1,2,3], [4,5,6], [1,2,3], [7,8,9], [1,2,3]]; const seen = new Map(); const arrAfter = []; for (const item of arrBefore) { // 用JSON字符串当唯一标识,也可以换成自定义的哈希值 const key = JSON.stringify(item); if (!seen.has(key)) { seen.set(key, true); arrAfter.push(item); } } console.log(arrAfter);
原理说明:
遍历数组时,把每个元素的“唯一标识”存在Map里,遇到已存在的标识就跳过,不存在的就加入结果数组。如果有特殊元素,也可以把JSON.stringify换成自定义的哈希生成函数。
优缺点:
- ✅ 时间复杂度O(n),大数据量下性能最优
- ✅ 代码简洁,比方案2高效
- ❌ 和方案1一样,默认依赖JSON序列化,特殊元素需要自定义哈希
总结选择建议:
- 普通场景(元素都是可序列化值):直接用方案1,简洁又高效
- 复杂场景(特殊元素/自定义相等规则):用方案2或方案3(搭配自定义哈希)
- 大数据量:优先选方案3
内容的提问来源于stack exchange,提问作者user3877230
相关产品推荐
相关产品推荐

