user3290805
user3290805

Reputation: 475

Find highest value from hash that contains "nil"

I have a hash which looks like this

@hash = {
  0=>[{"name"=>"guest", "value"=>7.9}],
  1=>[nil], 2=>[nil], 3=>[nil], 4=>[nil], 5=>[nil], 6=>[nil], 7=>[nil], 8=>[nil],
  9=>[nil], 10=>[nil], 11=>[nil], 12=>[nil], 13=>[nil], 14=>[nil], 15=>[nil],
  16=>[nil], 17=>[nil], 18=>[nil],
  19=>[{"name"=>"test", "value"=>2.5}],
  20=>[{"name"=>"roam", "value"=>2.5}],
  21=>[{"name"=>"test2", "value"=>1.58}],
  22=>[{"name"=>"dff", "value"=>1.9}],
  23=>[{"name"=>"dddd", "value"=>3.16}]
}

I want the highest value from this hash in a variable. The output should be

@h = 7.9 \\only float value which should be highest among all

so I am doing like this

@hash.each do |k, v|
  if !v.nil?
    @h= [v.flatten.sort{ |v1, v2| v2['value'] <=> v1['value'] }.first['value']]
  end
end

but sometimes it works, and most of the times it doesn't.

Upvotes: 0

Views: 83

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110685

I prefer @Shadwell's solution, but here's another way:

hash.select { |_,v| v.first }
    .max_by { |_,v| v.first["value"] }
    .last
    .first["value"]
  #=> 7.9

The steps (with all but one n=>[nil] element removed for readabiity):

hash = { 0=>[{"name"=>"guest", "value"=>7.9}],
         1=>[nil],
        19=>[{"name"=>"test",  "value"=>2.5}],
        20=>[{"name"=>"roam",  "value"=>2.5}],
        21=>[{"name"=>"test2", "value"=>1.58}],
        22=>[{"name"=>"dff",   "value"=>1.9}],
        23=>[{"name"=>"dddd",  "value"=>3.16}]}

h = hash.select { |_,v| v.first }
  #=> { 0=>[{"name"=>"guest", "value"=>7.9}],
  #    19=>[{"name"=>"test",  "value"=>2.5}],
  #    20=>[{"name"=>"roam",  "value"=>2.5}],
  #    21=>[{"name"=>"test2", "value"=>1.58}],
  #    22=>[{"name"=>"dff",   "value"=>1.9}],
  #    23=>[{"name"=>"dddd",  "value"=>3.16}]}
a = h.max_by { |_,v| v.first["value"] }
  #=> [0, [{"name"=>"guest", "value"=>7.9}]]
b = a.last
  #=> [{"name"=>"guest", "value"=>7.9}]
b.first["value"] 
  #=> 7.9

Upvotes: 0

Shadwell
Shadwell

Reputation: 34774

@hash.values.flatten.compact.map { |h| h["value"] }.max
=> 7.9

Which equates to:

  • Get the values of the hash as an array
  • Flatten all the elements in the values array
  • Compact to remove all nil entries
  • Map the remaining entries to the ["value"] element in the hash
  • Return the maximum of all those value

It makes a lot of assumptions about the format of your @hash though.

Upvotes: 6

Related Questions