Ruby 维护 Hash 插入顺序

Posted

技术标签:

【中文标题】Ruby 维护 Hash 插入顺序【英文标题】:Ruby maintain Hash insertion order 【发布时间】:2011-10-25 19:39:15 【问题描述】:

我正在寻找一种方法来维护我在 Ruby 中使用的哈希的插入顺序。我的数据来自数据库,并且已经按照我想要的方式进行了分组/排序,但是 Ruby 不保证在我的版本 1.8.4 中保持哈希顺序。

有什么解决方法吗?如果没有,我可以创建一个自定义比较器吗?

这是哈希:


"February"=>[0.5667, 14.6834, 79.7666, 261.8668, 342.1167, 723.517], 
"March"=>[0.0, 26.4667, 554.45, 681.3164, 2376.0668, 10353.0358], 
"May"=>[2.75, 34.6666, 342.1831, 1331.8999, 1589.617, 9282.9662], 
"July"=>[1.9, 2.3666, 59.45, 302.1501, 554.1652, 5195.0839], 
"June"=>[0.15, 24.2166, 244.1498, 335.6834, 536.067, 1498.949], 
"August"=>[0.0, 0.4, 9.3668, 30.7164, 67.7504, 162.0337], 
"April"=>[0.0, 8.3, 68.9331, 357.9168, 815.9662, 2870.217]
 

任何想法都会很棒, 谢谢

【问题讨论】:

【参考方案1】:

Ruby 自 1.9 版(2007 年 12 月发布)以来保持哈希顺序(参见:http://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash/)

此外,还有一个名为 orderedhash 的宝石用于旧红宝石。

【讨论】:

hash.merge 之类的东西会破坏它,因为许多哈希函数没有被覆盖,只是一个简单的例子。【参考方案2】:

您可以在包含排序顺序的键的一侧保留一个列表

最初:

hash = 
keys = []

插入时:

def insert(key, value)
  keys << key unless hash[key]
  hash[key] = value
end

按插入顺序迭代:

for key in keys do
  puts key, hash[key]
end

【讨论】:

如果我保留了一个按排序顺序包含键的列表,我如何使用它来对哈希进行排序?遍历每一对并交换不匹配的位置? 我只是注意到部分答案没有意义并删除了 由于@KimmoLehto 回答了 Ruby 1.9 的问题,因此对于较低版本,这个答案很好,但为了获得更好(~100x)的性能,请使用链表而不是数组。在这里查看原因:web.archive.org/web/20150215021253/http://khakimov.com/blog/…

以上是关于Ruby 维护 Hash 插入顺序的主要内容,如果未能解决你的问题,请参考以下文章

HashTable 是不是维护插入顺序?

维护插入顺序的 Java 集合

像frozenset这样维护插入顺序的数据结构?

为啥哈希表不保持插入顺序? [复制]

集合中常用算法总结

bzoj 1014 [JSOI2008]火星人prefix (splay+二分答案+字符串hash)