max_by返回错误的值

时间:2014-09-16 12:47:03

标签: ruby-on-rails ruby hash

我有哈希,看起来像这样

@hash =  { 1=>[], 2=>[], 3=>[], 4=>[],5=>[], 6=>[], 7=>[
[{"value"=>1.58, "title"=>"sun", "quantity" => 2}],
[{"value"=>1.99, "title"=>"sophia", "quantity" => 5}],
[{"value"=>6.30, "title"=>"roam", "quantity" => 15}],
[{"value"=>3.981, "title"=>"jia", "quantity" => "4"}]], 8 => [], 9 => [], 10 => [] }

我试图根据每个特定索引值的值标记找到最大值,例如

out put应该看起来像这样

    @hash =  { 1=>nil, 2=>nil, 3=> nil, 4=>nil,5=>nil, 6=>nil, 7=>[
[{"value"=>6.30, "title"=>"roam", "quantity" => 15}], 8 => nil, 9 => nil, 10 => nil }

我希望预期输出清晰

所以我试图通过以下代码获得最大值

  for t in 0..10
     if !@hash[t].nil?                                                                     
        @hash[t]  = @hash[t].max_by{|i| i[0]['value'].to_i} 
        puts "----------"
        puts @hash.to_s
     end
  end

但我只得到第一个值形式哈希,而其他索引则为null,而不是为该特定索引提供最大值。这个循环中的放置给了我这个 这是错误的

[{"title":"sun","value":1.58, "quantity => 2"}], null, null, null, null..

不知道出了什么问题

6 个答案:

答案 0 :(得分:2)

 @hash =  { 1=>[], 2=>[], 3=>[], 4=>[],5=>[], 6=>[], 7=>[
 [{"value"=>1.58, "title"=>"sun", "quantity" => 2}],
 [{"value"=>1.99, "title"=>"sophia", "quantity" => 5}],
 [{"value"=>6.30, "title"=>"roam", "quantity" => 15}],
 [{"value"=>3.981, "title"=>"jia", "quantity" => "4"}]], 8 => [], 9 => [], 10 => [] }

 @hash.each do |key, values|
   if values.empty?
     @hash[key] = nil
   else
     @hash[key] = [values.flatten.max_by{|h| h["value"]}]
   end
 end

 p @hash

答案 1 :(得分:0)

下面:

@hash =  { 1=>[], 2=>[], 3=>[], 4=>[],5=>[], 6=>[], 7=>[
[{"value"=>1.58, "title"=>"sun", "quantity" => 2}],
[{"value"=>1.99, "title"=>"sophia", "quantity" => 5}],
[{"value"=>6.30, "title"=>"roam", "quantity" => 15}],
[{"value"=>3.981, "title"=>"jia", "quantity" => "4"}]], 8 => [], 9 => [], 10 => [] }

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

puts @hash.inspect
#=> {1=>nil, 2=>nil, 3=>nil, 4=>nil, 5=>nil, 6=>nil, 7=>[{"value"=>6.3, "title"=>"roam", "quantity"=>15}], 8=>nil, 9=>nil, 10=>nil}

答案 2 :(得分:0)

我认为这可以满足您的需求:

@hash.map do |key, things|
  [
    key,
    things.max_by { |thing| thing.first["value"].to_i }
  ]
end.to_h

请原谅无用的变量名称,我不太清楚你的数据结构代表什么,所以我无法选择更好的名字。

请注意,这不会编辑@hash,但会返回新的哈希值。

答案 3 :(得分:0)

根据要求使用#max_by不确定为什么你以及许多其他答案想要破坏原始哈希。以下所有方法都是非破坏性的,并将返回请求的结果。< /强>)

 @hash.map.with_object({}) do |(k,v),obj|
   obj[k] = v.empty? ? nil : [v.flatten.max_by{ |h| h["value"]}]
 end
 #=>{1=>nil, 2=>nil, 3=>nil, 4=>nil, 5=>nil, 6=>nil, 7=>[{"value"=>6.3, "title"=>"roam", "quantity"=>15}], 8=>nil, 9=>nil, 10=>nil}

如果你不希望第7个元素成为1的数组,这对我来说没有多大意义,那就更清洁了。

@hash.map.with_object({}) do |(k,v),obj|
   obj[k] = v.flatten.max_by{ |h| h["value"]}
end
#=> {1=>nil, 2=>nil, 3=>nil, 4=>nil, 5=>nil, 6=>nil, 7=>{"value"=>6.3, "title"=>"roam", "quantity"=>15}, 8=>nil, 9=>nil, 10=>nil}

为什么你需要一个单个元素的数组,而这一切都会增加复杂性?除非你以后附加到这个元素?

或另一种方式

@hash.map.with_object({}) do |(k,v),obj|
  obj[k] = v.max_by{|a| a.is_a?(Array) ? a[0]['value'] : a.to_f}
end

答案 4 :(得分:0)

这里是提供所需输出的代码:

output_hash = {}

@hash.keys.each do |k|
  output_hash[k] = @hash[k].flatten.max{ |a, b| a["value"] <=> b["value"]  }
end

puts output_hash

答案 5 :(得分:0)

如果您只想要一个值,可以通过一个衬垫轻松完成,sort_by替换为max_by

对降序值进行排序

@hash.values.reject(&:empty?).flatten.sort_by{|x| x['value']}

最大值哈希

@hash.values.reject(&:empty?).flatten.max_by{|x| x['value']}