按键排序哈希,在Ruby中返回哈希

时间:2010-12-02 20:31:16

标签: ruby sorting hashmap

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

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}

11 个答案:

答案 0 :(得分:201)

在Ruby 2.1中很简单:

h.sort.to_h

答案 1 :(得分:79)

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

没有排序哈希的概念。所以不,你正在做的事情是不对的。

如果您希望将其排序以进行显示,请返回一个字符串:

"{" + 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

但总的来说,谈论排序的哈希是没有意义的。从docs开始,“通过键或值遍历散列的顺序可能看起来是任意的,并且通常不在插入顺序中。”因此,按特定顺序将密钥插入哈希将无济于事。

答案 2 :(得分:63)

我一直使用sort_by。您需要使用#sort_by包装Hash[]输出以使其输出散列,否则它将输出数组数组。或者,要完成此操作,您可以在元组数组上运行#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

How to sort a Ruby Hash by number value?”中有类似的问题。

答案 3 :(得分:13)

不,它不是(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倍以上

答案 4 :(得分:12)

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

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

答案 5 :(得分:6)

如果您不想使用ruby 1.9.2或推广自己的解决方法,

ActiveSupport::OrderedHash是另一种选择。

答案 6 :(得分:4)

  

排序哈希,在Ruby中返回哈希

使用解构和Hash#sort

hash.sort { |(ak, _), (bk, _)| ak <=> bk }.to_h

可枚举#sort_by

hash.sort_by { |k, v| k }.to_h

使用默认行为的哈希#排序

h = { "b" => 2, "c" => 1, "a" => 3  }
h.sort         # e.g. ["a", 20] <=> ["b", 30]
hash.sort.to_h #=> { "a" => 3, "b" => 2, "c" => 1 }

注意:&lt; Ruby 2.1

array = [["key", "value"]] 
hash  = Hash[array]
hash #=> {"key"=>"value"}

注意:&gt; Ruby 2.1

[["key", "value"]].to_h #=> {"key"=>"value"}

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

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

@equipments是我在我的模型上构建并在我的控制器上返回的哈希。如果你调用.sort,它将根据它的键值对哈希进行排序。

答案 9 :(得分:0)

我借鉴了 Boris Stitnicky 的灵感解决方案,将一个就地 sort! 方法修补到 Hash 中:

def sort!
  keys.sort!.each { |k| store k, delete(k) }
  self
end

答案 10 :(得分:-3)

我喜欢上一篇文章中的解决方案。

我制作了一个迷你课程,名为class AlphabeticalHash。它还有一个名为ap的方法,它接受一个参数Hash作为输入:ap variable。类似于pp(pp variable

但它会(按字母顺序)打印(按键)。 Dunno如果有其他人想要使用它,它可以作为宝石使用,你可以这样安装:gem install alphabetical_hash

对我来说,这很简单。如果其他人需要更多功能,请让我们 我知道,我会将它包含在宝石中。

编辑:信用转到Peter,他给了我这个想法。 :)