utinum
utinum

Reputation: 65

Find the most frequent number in PHP array

I have an array in PHP with repeating numbers and I would like to find the most frequent but only when there is only one of that.

while (count(array_count_values($arr)) > 1) {
$minim = min(array_count_values($arr));
while ($minim == min(array_count_values($arr))) {
    unset($arr[array_search(array_search(min(array_count_values($arr)), array_count_values($idList)), $arr)]);
    $arr = array_splice($arr, 0, 1);
}
}

In my code the first while runs until I have only one number (multiple times) in the array and with the second one I delete the less frequent numbers. My problem is the I get this error for my second min(): "Array must contain at least one element".

Upvotes: 3

Views: 1844

Answers (2)

Mulan
Mulan

Reputation: 135367

You could probably perform an array_reduce on the counts to find the max, but because array_reduce does not give you access to the iterable's key, you'd have to perform additional transformation.

Instead, I would recommend you build your own MaxHeap by extending from SplMaxHeap

class MaxHeap extends SplMaxHeap {
  public function compare($a, $b) {
    if (current($a) < current($b))
      return -1;
    elseif (current($a) > current($b))
      return 1;
    else
      return 0;
  }
}

Then we can use it as such – the answer says [ 7 => 4 ] which means: 7 is the most common number, appearing 4 times

$heap = new MaxHeap();
foreach (array_count_values($numbers) as $n => $count)
  $heap->insert([$n => $count]);

print_r($heap->top());
// [ 7 => 4 ]

printf("%d is the most common number, appearing %d times",
  key($heap->top()),
  current($heap->top())
);
// 7 is the most common number, appearing 4 times

complete script

$numbers = [0, 1, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 7, 7, 8, 8, 9];

class MaxHeap extends SplMaxHeap {
  public function compare($a, $b) {
    if (current($a) < current($b))
      return -1;
    elseif (current($a) > current($b))
      return 1;
    else
      return 0;
  }
}

$heap = new MaxHeap();
foreach (array_count_values($numbers) as $n => $count)
  $heap->insert([$n => $count]);

printf("%d is the most common number, appearing %d times",
  key($heap->top()),
  current($heap->top())
);

revision history

I was unaware of PHP's native array_count_values function. I removed the more complex array_reduce in favor of this super specialised function. Thanks, @CBroe.

Upvotes: 1

C3roe
C3roe

Reputation: 96383

I have an array in PHP with repeating numbers and I would like to find the most frequent but only when there is only one of that.

Your approach seems rather complicated.

Here's how I'd do that:

$numbers = [1, 6, 5, 6, 2, 1, 6, 7, 8]; // positive test case
//$numbers = [1, 6, 5, 6, 2, 1, 6, 7, 8, 1];  // negative test case

$count = array_count_values($numbers); // get count of occurrence for each number

arsort($count); // sort by occurrence, descending

$first = key($count); // get key of first element, because that is the/one
                      // of the highest number(s)
$count_first = current($count); // get occurrence for first array value
$count_second = next($count); // get occurrence for second array value

if($count_first != $count_second) { // did they occur in different frequencies?
  echo $first . ' occurred most in input array.';
}
else {
  echo 'input array contained multiple values with highest occurrence.';
}

Upvotes: 2

Related Questions