6

Here's a hash that keeps track of how much of each fruit I have

fruits = {"apples" => 10, "pears" => 15, "bananas" => 15, "grapes" => 12}

And I want to know which fruit I have the most of.
If there are tie-breakers then just return them all.

MxLDevs
  • 19,048
  • 36
  • 123
  • 194
  • 1
    Sorry, I didn't manage to get the 'tie-breaker' part. If the hash is the one in your example, I would just return all of them? – Pedro Nascimento May 22 '12 at 04:07
  • @Keikoku, can you clarify what "return all of them" means? Does it mean return the WHOLE hash? Or does it mean return just those keys tied for the top value? – Kent Rancourt May 22 '12 at 04:54
  • return just those that tied for the top value – MxLDevs May 22 '12 at 05:25
  • hash.max_by{|k,v| v} http://stackoverflow.com/questions/6040494/how-to-find-the-key-of-the-largest-value-hash and http://stackoverflow.com/questions/8008468/how-to-find-the-key-of-the-largest-value-hash-ruby – trushkevich Feb 18 '13 at 12:53

2 Answers2

8
# easy
max_quantity = fruits.values.max
max_fruits = fruits.select { |k, v| v == max_quantity }.keys

# fast                                                                          
max_quantity = -1.0/0.0
max_fruits = []
fruits.each do |k, v|
  if v > max_quantity
    max_quantity = v
    max_fruits = []
  end
  max_fruits.push k if v == max_quantity
end

Since exceptional cases are Bad(tm), both of these always return an array.

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • The select block is slower than the other one? – MxLDevs May 22 '12 at 04:19
  • I have not measured. To be sure, one is mostly native, the other mostly Ruby, so I might actually be incorrect :p but the top one will do four loops over data (`values`, `max`, `select`, `keys`), the bottom one will just do the one. The top one is definitely more readable, and in practice the speed advantage, even if it exists, would be negligible. The best value from the bottom example is actually learning how you can do it yourself, without the help from the library. – Amadan May 22 '12 at 04:21
6
max_value = fruits.values.max
keys = fruits.select{|k, v| v == max_value}.keys
xdazz
  • 158,678
  • 38
  • 247
  • 274
  • Does not address the issue "If there are tie-breakers then just return them all." – Amadan May 22 '12 at 03:48
  • Yes, it does. Will return `["pears", "bananas"]`. "Return them all" means return all the tie-breakers. – papiro Mar 02 '22 at 15:57