从包含“nil”的哈希中查找最高值

时间:2014-09-16 16:24:25

标签: ruby hash

我有一个看起来像这样的哈希

@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}]
}

我希望变量中此散列的值最高。输出应为

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

所以我这样做

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

但有时它会起作用,而且大部分时间都没有。

2 个答案:

答案 0 :(得分:6)

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

等同于:

  • 将哈希值作为数组获取
  • 展平数组数组中的所有元素
  • 压缩以删除所有nil条目
  • 将其余条目映射到哈希
  • 中的["value"]元素
  • 返回所有这些值的最大值

虽然对@hash的格式做了很多假设。

答案 1 :(得分:0)

我更喜欢@ Shadwell的解决方案,但这是另一种方式:

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

步骤(除了一个n=>[nil]元素之外的所有元素都已删除了可读性):

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