# Re: Mode method for Array

**URL:** <https://www.ruby-forum.com/t/re-mode-method-for-array/149907>\
**Category:** Ruby\
**Created:** [October 1, 2008, 1:15am UTC](https://www.ruby-forum.com/t/re-mode-method-for-array/149907 "2008-10-01T01:15:04Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![glenn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/4bbf92/32.png) [@glenn](https://www.ruby-forum.com/u/glenn)\
**Post date:** [October 1, 2008, 1:15am UTC](https://www.ruby-forum.com/t/re-mode-method-for-array/149907/1 "2008-10-01T01:15:04Z")

</div>

Hi,

I wrote 2 ways. I don’t know if either way is good or not. Any  
feedback is welcome.

The first way makes a hash of the array, with the unique values in the  
array as the keys, and the number of times the keys occur as the values.  
Then I create a new hash out of that first hash with the frequencies as  
the keys of the hash and the elements that had that frequency as the  
values. Then I pick out the value of the highest key.

The second way creates that frequency hash, then iterates over the hash  
and creates an array with the elements that have the highest frequency.

class Array  
def hash\_of\_frequency  
h = Hash.new(0)  
each\_with\_index do |e, i|  
e = e.to\_f if e != nil  
h[e] = h[e] += 1  
end  
h  
end

def get\_mode  
h = hash\_of\_frequency.frequency\_in\_key  
h[h.keys.max].sort  
end  
end

class Hash  
def frequency\_in\_key  
h = Hash.new { |k, v| k[v] = [] }  
each { |k, v| h[v] \<\< k if k != nil }  
h  
end

def get\_mode  
a = []  
max\_value = values.max  
each { |k, v| a \<\< k if v == max\_value }  
a  
end  
end

[3, 1, 1, 55, 55].hash\_of\_frequency.get\_mode.inspect ## returns [1.0,  
55.0]  
[3, 1, 1, 55, 55].get\_mode.inspect ## returns[1.0, 55.0]

----- Original Message ----  
From: EustÃ¡quio ‘TaQ’ Rangel [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
To: ruby-talk ML [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Sent: Tuesday, September 30, 2008 6:14:35 PM  
Subject: Re: Mode method for Array

> I’d like to write a get\_mode method for the Array class. The method would return an array of the most frequently occurring element or elements.  
> So [3, 1, 1, 55, 55].get\_mode would return [1, 55].  
> I have a way to do this but I don’t know if it’s the best way. I was wondering if anyone had any suggestions?

What is your way? Maybe we can have some idea of what parameters you are  
using  
to the the most frequently elements. Using something like

irb(main):001:0\> [3,1,1,55,55].inject(Hash.new(0)){|memo,item|  
memo[item] += 1;  
memo}.sort\_by {|e| e[1]}.reverse  
=\> [[55, 2], [1, 2], [3, 1]]

can return you some elements ordered by frequency.

---

<div class="post-metadata">

**Author:** ![glenn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/4bbf92/32.png) [@glenn](https://www.ruby-forum.com/u/glenn)\
**Post date:** [October 1, 2008, 1:16am UTC](https://www.ruby-forum.com/t/re-mode-method-for-array/149907/2 "2008-10-01T01:16:49Z")

</div>

On Sep 30, 2008, at 6:30 PM, Glenn wrote:

> key.  
> h[e] = h[e] += 1  
> end  
> h  
> end

You never use i, so just use each (and loose the second block parameter)

h[e] = h[e] += 1 ???  
Did you mean just: h[e] += 1

> h
> 
> [3, 1, 1, 55, 55].hash\_of\_frequency.get\_mode.inspect ## returns  
> [1.0, 55.0]  
> [3, 1, 1, 55, 55].get\_mode.inspect ## returns[1.0, 55.0]

If you don’t bother with the .to\_f on the elements, you could define  
this over ANY Enumerable with a variation on what TaQ posted;  
something like:

module Enumerable  
def mode  
alist = inject(Hash.new(0)) {|h,e| h[e]+=1;h}.sort\_by {|(e,c)| -c}  
alist.select {|(e,c)| c == alist[0][1]}.map{|(e,c)| e}  
end  
end

irb\> [3,1,1,55,55].mode  
=\> [55, 1]  
irb\> [‘dog’,‘dog’,‘cat’,‘bird’,5,5,42].mode  
=\> [5, “dog”]

-Rob

> > I have a way to do this but I don’t know if it’s the best way. I
> 
> can return you some elements ordered by frequency.

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![glenn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/4bbf92/32.png) [@glenn](https://www.ruby-forum.com/u/glenn)\
**Post date:** [October 1, 2008, 1:21am UTC](https://www.ruby-forum.com/t/re-mode-method-for-array/149907/3 "2008-10-01T01:21:30Z")

</div>

On Tue, Sep 30, 2008 at 6:02 PM, Rob B.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > keys of the hash and the elements that had that frequency as the values.  
> > h[e] = h[e] += 1  
> > h = hash\_of\_frequency.frequency\_in\_key
> > 
> > 55.0]  
> > end
> 
> irb\> [3,1,1,55,55].mode  
> =\> [55, 1]  
> irb\> [‘dog’,‘dog’,‘cat’,‘bird’,5,5,42].mode  
> =\> [5, “dog”]
> 
> -Rob

I was thinking similarly…

module Enumerable  
def mode  
h, max = inject(Hash.new(0)) {|h, i| h[i] += 1; h}, h.values.max  
h.select {|k, v| v == max}.transpose.first  
end  
end

p [3, 1, 55, 1, 55].mode

=\> [55, 1]

Sort afterward if you want.

Todd
