这是对哈希排序并返回哈希对象(而不是数组)的最佳方法吗?
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}
这是对哈希排序并返回哈希对象(而不是数组)的最佳方法吗?
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}
Answers:
在Ruby 2.1中,它很简单:
h.sort.to_h
h.sort{|a,z|a<=>z}.to_h
测试2.1.10、2.3.3 )
a
是一个数组,而不仅仅是键)。我已删除我的评论。
h.map(&:sort).map(&:to_h)
。
注意: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中,“您通过键或值遍历哈希的顺序似乎是任意的,并且通常不会按插入顺序进行。” 因此,按特定顺序将密钥插入哈希将无济于事。
我一直都习惯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
“ 如何按数字值对Ruby哈希排序? ”中有一个类似的问题。
sort_by
一个散列将返回的数组。您将需要再次将其映射为哈希。Hash[hsh.sort_by{|k,v| v}]
hsh.sort_by(&:last).to_h => {"b"=>10, "a"=>1000, "c"=>200000}
。
to_h
在Ruby的2.1.0+只支持
sort_by{|k,v| v}.to_h)
不,不是(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]
如果您渴望更多的可能性,这里是对原始哈希进行就地修改以使其排序的方法:
h.keys.sort.each { |k| h[k] = h.delete k }
按键对哈希排序,在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"}
v
,则应在下划线hash.sort_by { |k, _v| k }.to_h
如果您不想使用ruby 1.9.2或使用自己的解决方法,则ActiveSupport :: OrderedHash是另一个选择。
@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上正常运行。