Reputation: 329
Given this array of hashes here:
arr = [{:question_type=>"Fire", :total=>0.0}, {:question_type=>"Water", :total=>0.0}, {:question_type=>"Metal", :total=>0.0}, {:question_type=>"Earth", :total=>0.0}, {:question_type=>"Wood", :total=>100.0}]
I would like to pick the hash with the highest value for the total key. So the code bellow seems to do the work
max = arr.max_by{|x| x[:total]}
puts max[:question_type]
#=> Wood
However if I have 2 hashes with the same value it will return the first one only
arr2 = [{:question_type=>"Fire", :total=>0.0}, {:question_type=>"Water", :total=>0.0}, {:question_type=>"Metal", :total=>0.0}, {:question_type=>"Earth", :total=>50.0}, {:question_type=>"Wood", :total=>50.0}]
max = arr2.max_by{|x| x[:total]} #it should be arr2
puts max[:question_type]
#=> Earth
What would be the best way to get it to return Earth
and Wood
in case both are the highest values?
Upvotes: 1
Views: 2231
Reputation: 4226
An alternative approach to some solid answers already posted here is to roll your own method to retrieve the max values, including multiples if there are ties:
def get_max(arr)
result = []
current_max = 0.0
arr.each do |hash|
if hash[:total] > current_max
result = [hash[:question_type]]
current_max = hash[:total]
elsif hash[:total] == current_max
result.push(hash[:question_type])
end
end
result
end
arr = [{:question_type=>"Fire", :total=>0.0}, {:question_type=>"Water", :total=>0.0}, {:question_type=>"Metal", :total=>0.0}, {:question_type=>"Earth", :total=>50.0}, {:question_type=>"Wood", :total=>50.0}]
puts get_max(arr)
# => ["Earth", "Wood"]
It may not be as succinct as using something like #max_by
and #select
, but the benefit of the above approach is you only iterate through the array once.
Hope it helps!
Upvotes: 0
Reputation: 44581
You can do this with group_by
and max
:
arr.group_by { |x| x[:total] }.max.last
Upvotes: 6
Reputation: 6026
You could do this in tow steps this way:
max = arr.max_by{|x| x[:total]}
max = arr.select{ |x| x[:total] == max[:total }
Upvotes: 1
Reputation: 7545
You can always just take that max value and select
.
arr = [{:question_type=>"Fire", :total=>0.0}, {:question_type=>"Water", :total=>0.0}, {:question_type=>"Metal", :total=>0.0}, {:question_type=>"Earth", :total=>50.0}, {:question_type=>"Wood", :total=>50.0}]
max = arr.max_by{|x| x[:total]}
max_values = arr.select{|hash| hash[:total] == max[:total]}
Upvotes: 0