这是将哈希表排序并返回哈希对象(而不是数组)的最佳方法吗:
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
h.sort{|a,z|a<=>z}.to_h
(已测试2.1.10、2.3.3)。 - whitehat101a
是一个数组,而不仅仅是键)。我已经删除了我的评论。 - zachaysanh.map(&:sort)。map(&:to_h)
。 - J.M. Janzenh.keys.sort.map { |k| [k, h[k]] }.to_h
慢10倍。不确定在C级别上有何差异,但在基准测试中非常明显。即使是 sort_by(&:first)
也要快得多。 - Kaplan Ilya"{" + 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
在 "如何按数字值对 Ruby 哈希进行排序?" 中有一个类似的问题。
sort_by
将返回一个数组。您需要将其映射回哈希表。Hash[hsh.sort_by{|k,v| v}]
- stevenspielhsh.sort_by(&:last).to_h => {"b"=>10, "a"=>1000, "c"=>200000}
。 - Cary Swovelandto_h
仅在 Ruby 2.1.0 及以上版本中受支持。 - Phrogzsort_by{|k,v| v}.to_h)
。 - jitter按照 键 对哈希进行排序,在 Ruby 中返回哈希
使用 解构赋值 和 Hash#sort
hash.sort { |(ak, _), (bk, _)| ak <=> bk }.to_h
Enumerable#sort_by
hash.sort_by { |k, v| k }.to_h
使用默认行为的 Hash#sort 方法
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 }
注意: < Ruby 2.1
array = [["key", "value"]]
hash = Hash[array]
hash #=> {"key"=>"value"}
注意: > Ruby 2.1
[["key", "value"]].to_h #=> {"key"=>"value"}
hash.sort_by { |k, _v| k }.to_h
如果不使用 v
,你应该在变量名前加下划线。 - silva96在问题描述中,您给出了最佳的答案:Hash[h.sort]
如果您想要更多可能性,这里提供了使原始哈希在原地进行排序的修改方法:
h.keys.sort.each { |k| h[k] = h.delete k }
不是的,它不支持(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倍甚至更多。
ActiveSupport::OrderedHash是另一个选择,如果你不想使用ruby 1.9.2或自己编写解决方法。
sort
方法,然后使用to_h
方法将数组转换回哈希表。h = { "a" => 1, "c" => 3, "b" => 2, "d" => 4 }
h.sort.to_h
# => { "a" => 1, "b" => 2, "c" => 3, "d" => 4 }
@ordered = {}
@unordered.keys.sort.each do |key|
@ordered[key] = @unordered[key]
end
我遇到了同样的问题(需要按照设备名称对我的设备进行排序),我是这样解决的:
<% @equipments.sort.each do |name, quantity| %>
...
<% end %>
@equipments 是我在模型上构建并在控制器上返回的哈希表。如果您调用 .sort,它将根据其键值对哈希表进行排序。
each
或each_pair
来迭代哈希表,否则我不确定对哈希表进行排序是否有太多优势。即使在这种情况下,我可能仍然会获取键,对其进行排序,然后迭代键并根据需要获取相应的值。这样可以确保代码在旧版本的Ruby上正确运行。 - the Tin Man