
本文介绍一种高效、无循环的 php 方法,通过组合 array_diff、array_diff_assoc 和 array_unique,精准剔除数组中所有重复项(即只保留出现次数为 1 的元素),完美解决 array_unique 仅去重而非“去重项”的常见误区。
本文介绍一种高效、无循环的 php 方法,通过组合 array_diff、array_diff_assoc 和 array_unique,精准剔除数组中所有重复项(即只保留出现次数为 1 的元素),完美解决 array_unique 仅去重而非“去重项”的常见误区。
在 PHP 开发中,一个常见但易被误解的需求是:不是简单地“去重”(保留每个值的第一个出现),而是彻底移除所有重复值——即只保留那些在整个数组中唯一出现(频次为 1)的元素。例如,给定数组:
$arr = [
0 => "Sat 2",
1 => "Sun 3",
2 => "Mon 4",
3 => "Tue 5",
4 => "Mon 4",
];目标结果应为:
[
0 => "Sat 2",
1 => "Sun 3",
3 => "Tue 5"
]注意:"Mon 4" 出现了两次,因此整个值被完全剔除,而非仅保留其首次出现。
array_unique() 无法满足此需求——它仅保留每个值的首次出现,返回 [0=>"Sat 2", 1=>"Sun 3", 2=>"Mon 4", 3=>"Tue 5"],仍包含冗余项。
立即学习“PHP免费学习笔记(深入)”;
✅ 正确解法是使用三函数组合,实现零循环、高可读性的单行逻辑:
$result = array_diff($arr, array_diff_assoc($arr, array_unique($arr)));
原理拆解:
- array_unique($arr) → 去重后保留首次索引:[0=>"Sat 2", 1=>"Sun 3", 2=>"Mon 4", 3=>"Tue 5"]
- array_diff_assoc($arr, array_unique($arr)) → 找出“原数组中与去重结果不一致的键值对”(即所有重复项的后续出现):[4=>"Mon 4"]
- array_diff($arr, [...]) → 从原数组中排除所有在上一步中识别出的重复值(注意:array_diff 按值比较,不依赖键)→ 最终剔除所有 "Mon 4" 实例
⚠️ 注意事项:
- 该方法严格按值匹配剔除,若存在不同键但相同值的多个元素,它们将全部被移除;
- 原数组键名会被保留(非数字索引亦有效),但 array_diff 返回结果会重置为数字索引;如需保持原始键,可改用 array_filter + array_count_values 方案(见下文备选);
- 对于大数组,此方案性能优于手动 foreach 计数,因底层由 C 实现且避免了 PHP 层循环开销。
? 备选方案(需保持原始键且逻辑更直观):
$counts = array_count_values($arr); $result = array_filter($arr, fn($v) => $counts[$v] === 1); // $result 键名与原数组一致,值仅含出现一次的元素
总结:当业务要求“宁缺毋滥”式去重(即重复即清除),请放弃 array_unique,优先采用 array_diff + array_diff_assoc + array_unique 组合式声明式写法——简洁、高效、语义明确。



















