【问题标题】:How to sort not simple hash (hash of hashes)如何排序不简单的散列(散列的散列)
【发布时间】:2010-09-26 14:25:43
【问题描述】:

我有一个这样的哈希

{ 55 => {:value=>61, :rating=>-147},
  89 => {:value=>72, :rating=>-175},
  78 => {:value=>64, :rating=>-155},
  84 => {:value=>90, :rating=>-220},
  95 => {:value=>39, :rating=>-92},
  46 => {:value=>97, :rating=>-237},
  52 => {:value=>73, :rating=>-177},
  64 => {:value=>69, :rating=>-167},
  86 => {:value=>68, :rating=>-165},
  53 => {:value=>20, :rating=>-45}
}

如何按 :rating 对其进行排序?或者也许我应该使用一些不同的结构?

【问题讨论】:

  • 可能值得注意的是标题中的编程语言。

标签: ruby sorting hash


【解决方案1】:

我会将数据结构更改为哈希数组:

my_array =
[
  {:id => 78, :value=>64, :rating=>-155},
  {:id => 84, :value=>90, :rating=>-220},
  {:id => 95, :value=>39, :rating=>-92}
]

您可以轻松地对这种结构进行排序

my_array.sort_by { |record| record[:rating] }

要获得通过 id 获取记录的类似哈希的功能,您可以在 my_array 上定义一个新方法:

def my_array.find_by_id(id) 
  self.find { |hash| hash[:id] == id }
end

然后你就可以这样做了

my_array.find_by_id(id)

而不是

my_hash[id]

【讨论】:

  • 不确定此评论是否会在 4 年后得到答复......我使用哈希的原因是使用一个可以直接访问和递增值的键,例如 h[436246 ]。填充哈希后,我应该转换为数组
  • 您可以使用Hash[my_array.sort_by { |record| record[:rating] }] 再次将其转换回哈希。如果使用 Ruby 1.9.x 或更高版本,因为它在内部维护哈希的排序顺序。
  • 感谢这为我破解了它。可以使用更好的数据结构!.....即使这篇文章太老了,我也学到了一些东西:)
【解决方案2】:

Ruby 中的哈希不能排序(至少在 1.9 之前不能)

这意味着循环遍历哈希不一定会以正确的顺序为您生成信息。但是,通过首先将哈希数据转换为数组来按特定顺序循环遍历哈希数据是微不足道的,实际上调用哈希上的排序方法会将其转换为数组:

>> { :a => 4, :b => 12, :c => 3, :d => 8 }.sort_by { |key, value| value }
=> [[:c, 3], [:a, 4], [:d, 8], [:b, 12]]

所以在你的情况下:

hsh.sort_by {|key, ratings| ratings[:rating] }

【讨论】:

  • @Gaius - 感谢您的编辑,但代码按照编写的方式工作。我的全部观点是#sort_by 隐式地进行数组转换,而无需将 .to_a 插入 - 即使在 Ruby 1.8 中也是如此
【解决方案3】:

可能有更好的数据结构,但是(我假设这是 ruby​​)可以在 Ruby 中通过使用内联排序样式来完成,基本上告诉它如何比较两者。这是一个具体的例子:

my_hash = { 
  55 => {:value=>61, :rating=>-147},
  89 => {:value=>72, :rating=>-175},
  78 => {:value=>64, :rating=>-155},
  84 => {:value=>90, :rating=>-220},
  95 => {:value=>39, :rating=>-92},
  46 => {:value=>97, :rating=>-237},
  52 => {:value=>73, :rating=>-177},
  64 => {:value=>69, :rating=>-167},
  86 => {:value=>68, :rating=>-165},
  53 => {:value=>20, :rating=>-45}
}

puts "MY HASH"
my_hash.each do |local|
  puts local
end

sorted_hash = my_hash.sort  { | leftval, rightval | rightval[1][:rating]<=>leftval[1][:rating] }

puts "SORTED HASH"
sorted_hash.each do |local|
  puts local
end

【讨论】:

  • 这里不会有太大区别,但是#sort 对于计算字段通常效率低下。这是因为它将重新计算 every 比较的排序标准。 #sort_by 只为原始数组中的每个项目计算一次条件
猜你喜欢
  • 2014-05-19
  • 2015-01-26
  • 2013-05-16
  • 1970-01-01
  • 2014-01-08
  • 2017-10-13
  • 2011-10-06
  • 2010-11-02
  • 2013-03-15
相关资源
最近更新 更多