按键sorting散列,在Ruby中返回散列

这是sorting哈希和返回哈希对象(而不是数组)的最佳方法:

h = {"a"=>1, "c"=>3, "b"=>2, "d"=>4} # => {"a"=>1, "c"=>3, "b"=>2, "d"=>4} Hash[h.sort] # => {"a"=>1, "b"=>2, "c"=>3, "d"=>4} 

在Ruby 2.1中很简单:

 h.sort.to_h 

注意:Ruby> = 1.9.2有一个保存顺序的散列:顺序键被插入的顺序就是它们被枚举的顺序。 以下适用于旧版本或向后兼容的代码。

没有sorting哈希的概念。 所以不,你在做什么是不对的。

如果你想要它被分类显示,返回一个string:

 "{" + h.sort.map{|k,v| "#{k.inspect}=>#{v.inspect}"}.join(", ") + "}" 

或者,如果你想按键顺序:

 h.keys.sort 

或者,如果要按顺序访问元素:

 h.sort.map do |key,value| # keys will arrive in order to this block, with their associated value. end 

但是总而言之,谈论一个有序的散列是没有意义的。 从文档中 ,“您通过键或值遍历散列的顺序可能看起来是任意的,并且通常不会处于插入顺序中。” 因此,以特定顺序将密钥插入哈希将无济于事。

我一直使用sort_by 。 您需要使用Hash[]封装#sort_by输出,以使其输出散列,否则会输出数组数组。 或者,为了实现这一点,你可以在元组数组上运行#to_h方法将它们转换为k=>v结构(散列)。

 hsh ={"a" => 1000, "b" => 10, "c" => 200000} Hash[hsh.sort_by{|k,v| v}] #or hsh.sort_by{|k,v| v}.to_h 

在“ 如何按数字值sortingruby哈希 ”中有类似的问题。

不,它不是(Ruby 1.9.x)

 require 'benchmark' h = {"a"=>1, "c"=>3, "b"=>2, "d"=>4} many = 100_000 Benchmark.bm do |b| GC.start b.report("hash sort") do many.times do Hash[h.sort] end end GC.start b.report("keys sort") do many.times do nh = {} h.keys.sort.each do |k| nh[k] = h[k] end end end end user system total real hash sort 0.400000 0.000000 0.400000 ( 0.405588) keys sort 0.250000 0.010000 0.260000 ( 0.260303) 

对于大的哈希差异将会增长到10倍甚至更多

你在OP中给自己最好的答案: Hash[h.sort]如果你渴望更多的可能性,这里是对原始哈希进行就地修改,使其sorting:

 h.keys.sort.each { |k| h[k] = h.delete k } 

ActiveSupport :: OrderedHash是另一种select,如果你不想使用ruby1.9.2或滚动自己的解决方法。

 @ordered = {} @unordered.keys.sort.each do |key| @ordered[key] = @unordered[key] end 

我有同样的问题(我不得不按照他们的名字对我的设备进行分类),我解决了这个问题:

 <% @equipments.sort.each do |name, quantity| %> ... <% end %> 

@equipments是我build立在我的模型上的哈希,并在我的控制器上返回。 如果你调用.sort,它会根据它的关键值对散列进行sorting。

我喜欢上一篇文章的解决scheme。

我做了一个迷你class,叫它class AlphabeticalHash 。 它也有一个名为ap的方法,它接受一个参数Hash作为input: ap variable 。 类似于pp( pp variable

但它会(尝试和)按字母顺序列表(其键)打印。 不知道是否有其他人想使用它,它可以作为一个gem,你可以这样安装它: gem install alphabetical_hash

对我来说,这很简单。 如果别人需要更多的function,让我知道,我会把它纳入gem。

编辑:信贷去给彼得 ,谁给了我这个想法。 🙂