
本文介绍在 php 7.1+ 中,如何不仅过滤掉重复项,更将所有出现次数大于 1 的元素(包括首次出现的“原始项”)全部剔除,仅保留真正唯一的数组子项。
本文介绍在 php 7.1+ 中,如何不仅过滤掉重复项,更将所有出现次数大于 1 的元素(包括首次出现的“原始项”)全部剔除,仅保留真正唯一的数组子项。
在处理多维数组去重时,array_unique() 默认行为是保留首个唯一值、剔除后续重复项——这适用于“去重留一”,但不满足“完全剔除所有重复痕迹”的需求。本文场景要求:只要某元素在数组中出现 ≥2 次,则该元素的所有实例(含第一次)均被移除,最终结果只包含严格意义上的“独一份”数据。
实现这一目标的核心思路是两步走:
- 统计频次:提取关键字段(如 id)形成一维索引,再用 array_count_values() 统计每个值的出现次数;
- 精准过滤:遍历原数组,仅保留那些关键字段计数为 1 的元素。
以下是完整可运行示例(兼容 PHP 7.1+,使用箭头函数需 PHP 7.4+;若需兼容 7.1,请改用匿名函数):
<?php $array = [
['id' => 1, 'number' => 12345, 'date' => '2022-05-09'],
['id' => 2, 'number' => 123456, 'date' => '2022-05-09'],
['id' => 3, 'number' => 123456, 'date' => '2022-05-09'],
['id' => 3, 'number' => 123456, 'date' => '2022-05-09'],
];
// 步骤1:按'id'列提取所有值并统计频次
$counts = array_count_values(array_column($array, 'id'));
// 步骤2:过滤出'id'仅出现1次的完整子数组
$result = array_filter($array, function ($item) use ($counts) {
return $counts[$item['id']] === 1;
});
// 重置键名以获得连续数字索引(可选)
$result = array_values($result);
print_r($result);
?>
输出结果:
Array
(
[0] => Array
(
[id] => 1
[number] => 12345
[date] => 2022-05-09
)
[1] => Array
(
[id] => 2
[number] => 123456
[date] => 2022-05-09
)
)
✅ 关键说明:
- array_column($array, 'id') 高效提取所有 id 值,生成一维数组 [1,2,3,3];
- array_count_values() 将其转为频次映射 ['1'=>1, '2'=>1, '3'=>2];
- array_filter() 结合闭包,对每个子数组判断 $counts[$item['id']] === 1,确保只保留“全局唯一”的记录;
- array_values() 用于重置数组键名,避免因 array_filter() 保留原始键而产生非连续索引(如 [0]=>..., [1]=>...)。
⚠️ 注意事项:
- 若需基于多个字段(如 id + number)联合判重,应先用 array_map() 构造复合键(例如 "$item['id']-$item['number']"),再统计频次;
- 确保目标字段(如 'id')在所有子数组中存在且类型一致,否则 array_column() 可能返回 null 并影响统计;
- 该方法时间复杂度为 O(n),性能优于嵌套循环,适合中等规模数据(万级以内)。
此方案逻辑清晰、代码简洁、语义明确,是解决“彻底清除重复项”问题的标准实践。










