On Sep 30, 2008, at 6:30 PM, Glenn wrote: > 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 alues. 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 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 > 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] 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 > ----- Original Message ---- > From: EustáÒuio 'TaQ' Rangel <eustaquiorangel / gmail.com> > To: ruby-talk ML <ruby-talk / ruby-lang.org> > 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 re 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. Rob Biedenharn http://agileconsultingllc.com Rob / AgileConsultingLLC.com