如何在Ruby中的哈希列表中为每个键提取更大的值

我可以想象有一种简单的方法可以做到这一点而不是使用许多变量和状态。

我只想获得散列列表中每个键的最高值

例如:

[{1=>19.4}, {1=>12.4}, {2=>29.4}, {3=>12.4}, {2=>39.4}, {2=>59.4}] 

结果

 [{1=>19.4}, {3=>12.4}, {2=>59.4}] 

我会这样做:

 a = [{1=>19.4}, {1=>12.4}, {2=>29.4}, {3=>12.4}, {2=>39.4}, {2=>59.4}] # the below is the main trick, to group the hashes and sorted the key/value pair # in **ascending order**. a.sort_by(&:to_a) # => [{1=>12.4}, {1=>19.4}, {2=>29.4}, {2=>39.4}, {2=>59.4}, {3=>12.4}] # then using the trick in mind, we know hash can't have duplicate keys, so # blindly I can rely on `Enumerable#inject` with the `Hash#merge` method. a.sort_by(&:to_a).inject(:merge) # => {1=>19.4, 2=>59.4, 3=>12.4} # final one a.sort_by(&:to_a).inject(:merge).map { |k,v| {k => v} } # => [{1=>19.4}, {2=>59.4}, {3=>12.4}] 

这是@Matt答案的变体:

  a.group_by(&:keys).map {|k,v| {k.first => v.map(&:values).flatten.max}} #=> [{1=>19.4}, {2=>59.4}, {3=>12.4}] 

这个怎么样?

 Hash[a.flat_map(&:to_a).sort_by(&:last)] # a.flat_map(&:to_a).sort_by(&:last).to_h for Ruby 2.1+ as @steenslag suggested => {3=>12.4, 1=>19.4, 2=>59.4} 

这是fruity基准比较:

 require 'fruity' a = 1000.times.collect { |i| { rand(100) => rand(1000) } } compare do caryswoveland { a.group_by(&:keys).map {|k,v| {k.first => v.map(&:values).flatten.max}} } matt { a.group_by(&:keys).map { |k,v| v.max_by { |j| j[k[0]] } } } steenslag { a.each_with_object({}){|h, res| res.merge!(h){|k, *vals| res[k] = vals.max} } } abdo { Hash[a.flat_map(&:to_a).sort_by(&:last)] } end 

输出:

 Running each test 4 times. Test will take about 1 second. abdo is similar to steenslag (results differ..) steenslag is faster than matt by 30.000000000000004% ± 10.0% matt is faster than caryswoveland by 30.000000000000004% ± 10.0% 
 a = [{1=>19.4}, {1=>12.4}, {2=>29.4}, {3=>12.4}, {2=>39.4}, {2=>59.4}] p a.each_with_object({}){|h, res| res.merge!(h){|k, *vals| res[k] = vals.max} } #=> {1=>19.4, 2=>59.4, 3=>12.4} 
 a = [{1=>19.4}, {1=>12.4}, {2=>29.4}, {3=>12.4}, {2=>39.4}, {2=>59.4}] a.group_by(&:keys).map { |k,v| v.max_by { |j| j[k[0]] } } 

[{1 => 19.4},{2 => 59.4},{3 => 12.4}]

感谢Cary Swoveland获得group_by(&:keys)