PHP数组重复项检测及出现次数统计:代码逻辑错误排查
数组重复项统计错误分析与修正
问题背景
需求:给定数字数组,以键值对(关联数组)形式输出重复项及其出现次数。
给定数组:
$arr = [1,2,2,2,4,5,5,5,8,9,10,2,5,9,10,10];
期望结果:
Array ( [2] => 4 [5] => 4 [9] => 2 [10] => 3 )
尝试的代码:
$arr = [1,2,2,2,4,5,5,5,8,9,10,2,5,9,10,10]; sort($arr); $duplicates = []; $count = 1; // I assumed that at least one element is always there so I did not take 0 (if I am not wrong) for($i = 0; $i<count($arr); $i++){ for($j = $i+1; $j<count($arr); $j++){ if($arr[$i] == $arr[$j]){ if(!in_array($arr[$j], $duplicates)){ // array_push($duplicates, $arr[$j]); $count++; $duplicates[$arr[$j]] = $count; } }else{ $count = 1; } } } echo "<pre>"; print_r($duplicates);
当前错误输出:
Array ( [2] => 2 [5] => 2 [9] => 2 [10] => 4 )
错误原因
你的代码逻辑存在多处核心问题:
in_array判断逻辑错误:$duplicates是关联数组,in_array($arr[$j], $duplicates)检查的是数组中的值而非键,完全无法正确判断当前元素是否已被统计。比如当$duplicates[2] = 2时,in_array(2, $duplicates)会返回true,但这不是你需要的“判断键是否存在”的逻辑。- 嵌套循环的计数逻辑混乱:外层循环每个元素都和后续所有元素比较,同一个元素会被多次触发
count++,且count的重置时机错误。比如遍历到第一个2时,j匹配到第二个2会让count变成2,匹配到第三个2时,因为in_array(2, $duplicates)为true,不会执行计数;但当外层循环到第二个2时,j又会匹配后面的2,此时in_array(2, $duplicates)还是true,不会更新计数,导致最终统计值远小于实际次数。 - 重复统计逻辑错误:嵌套循环逐个比较元素的方式,无法准确统计每个元素的总出现次数,反而会因为多次循环导致计数混乱。
修正方案
方案1:使用PHP内置函数(最简单高效)
PHP提供了array_count_values()函数,可以直接统计数组中每个值的出现次数,之后只需过滤掉出现次数为1的元素即可:
$arr = [1,2,2,2,4,5,5,5,8,9,10,2,5,9,10,10]; $counts = array_count_values($arr); // 过滤掉只出现一次的元素 $duplicates = array_filter($counts, function($value) { return $value > 1; }); echo "<pre>"; print_r($duplicates);
方案2:手动修正循环逻辑
如果不想用内置函数,可以通过一次遍历完成统计,无需嵌套循环:
$arr = [1,2,2,2,4,5,5,5,8,9,10,2,5,9,10,10]; $duplicates = []; foreach($arr as $num) { // 如果键已存在,计数+1,否则初始化为1 if(isset($duplicates[$num])) { $duplicates[$num]++; } else { $duplicates[$num] = 1; } } // 过滤掉只出现一次的元素 $duplicates = array_filter($duplicates, function($value) { return $value > 1; }); echo "<pre>"; print_r($duplicates);
两种方案都能得到你期望的结果。
内容的提问来源于stack exchange,提问作者Aurazo Script
相关产品推荐
相关产品推荐

