这是对哈希进行排序并返回hash对象(而不是Array)的最佳方法吗?
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}
这是对哈希进行排序并返回hash对象(而不是Array)的最佳方法吗?
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 >= 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
但总的来说,谈论一个排序的哈希是没有意义的。从文档中可以看出,“按键或值遍历哈希的顺序似乎是任意的,通常不是插入顺序。”因此,以特定顺序向散列中插入键是没有用的。
其他回答
不,它不是(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倍甚至更多
我喜欢之前帖子中的解决方案。
我做了一个迷你类,叫它class AlphabeticalHash。它还有一个叫做ap的方法,它接受一个参数,一个Hash,作为输入:ap变量。类似于pp (pp变量)
但它将(试着)按字母顺序打印(它的键)。不知道是否有人想使用这个,它是一个gem,你可以这样安装它:gem install alphabetical_hash
对我来说,这很简单。如果其他人需要更多的功能,让 我知道,我会把它加进宝石里的。
编辑:这要归功于彼得,是他给了我这个想法。:)
我借用Boris Stitnicky的灵感解决方案来修补一个就地排序!方法:
def sort!
keys.sort!.each { |k| store k, delete(k) }
self
end
@ordered = {}
@unordered.keys.sort.each do |key|
@ordered[key] = @unordered[key]
end
如果你不想使用ruby 1.9.2或使用你自己的变通方法,ActiveSupport::OrderedHash是另一个选择。