1

I'm trying to figure out how to find a count of the most frequent element in an array of integers. I can think of a few methods that might be helpful but when I get to writing an expression inside the block I get complete lost on how to compare an element with the next and previous element. Any ideas? All help is really really appreciated!!!

  • That this question is a duplicate is hardly surprising. It's not clear, however, which question it's a dup of. My reading of the question is that the max count is to be returned ("...how to find a count of the most frequent element in an array..."). (See @Tadman's comment on my answer.) The source of "This question already has an answer here:" asks for the element whose count is greatest. Granted, it's a very short step from the answer to that question to obtaining the max count, but there may be better ways if only the max count is desired. – Cary Swoveland Aug 29 '16 at 17:30

1 Answers1

4

An easy was is to determine all the unique values, convert each to its count in the array, then determine the largest count.

def max_count(arr)
  arr.uniq.map { |n| arr.count(n) }.max
end

For example:

arr = [1,2,4,3,2,6,3,4,2]
max_count(arr)
  #=> 3

There are three steps:

a = arr.uniq
  #=> [1, 2, 4, 3, 6] 
b = a.map { |n| arr.count(n) }
  #=> [1, 3, 2, 2, 1] 
b.max
  #=> 3 

A somewhat more efficient way (because the elements of arr are enumerated only once) is to use a counting hash:

def max_count(arr)
  arr.each_with_object(Hash.new(0)) { |n,h| h[n] += 1 }.values.max
end

max_count(arr)
  #=> 3

We have:

a = arr.each_with_object(Hash.new(0)) { |n,h| h[n] += 1 }
  #=> {1=>1, 2=>3, 4=>2, 3=>2, 6=>1} 
b = a.values
  #=> [1, 3, 2, 2, 1] 
b.max
  #=> 3 

See Hash::new for an explanation of Hash.new(0). Briefly, if h = Hash.new(0) and h does not have a key k, h[k] will return the default value, which here is zero. h[k] += 1 expands to h[k] = h[k] + 1, so if h does not have a key k, this becomes h[k] = 0 + 1. On the other hand, if, say, h[k] => 2, then h[k] = h[k] + 1 #=> h[k] = 3 + 1.

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • Don't forget [`max_by`](http://ruby-doc.org/core-2.3.1/Enumerable.html#method-i-max_by). – tadman Aug 29 '16 at 17:11
  • @tadman, I considered `max_by`, but it's the max count, not the element having the max count, that is wanted. If I used `max_by` I'd need to recompute the count for that element, which did not appeal. – Cary Swoveland Aug 29 '16 at 17:14
  • That's one interpretation of the question, it's true. I read it the other way of wanting the most frequent element *based on* count. – tadman Aug 29 '16 at 17:17
  • Thanks Cary! Very informative with your solution. Really helped my understanding. – Austin Atendido Aug 29 '16 at 18:13