例如,我有一些单个哈希值
a = [{a: :b}, {c: :d}]
Run Code Online (Sandbox Code Playgroud)
将它转换成这个的最佳方法是什么?
{a: :b, c: :d}
Run Code Online (Sandbox Code Playgroud)
How*_*ard 116
你可以用
a.reduce Hash.new, :merge
Run Code Online (Sandbox Code Playgroud)
直接产生
{:a=>:b, :c=>:d}
Run Code Online (Sandbox Code Playgroud)
请注意,在发生碰撞的情况下,订单很重要.后置哈希覆盖以前的映射,请参阅例如:
[{a: :b}, {c: :d}, {e: :f, a: :g}].reduce Hash.new, :merge # {:a=>:g, :c=>:d, :e=>:f}
Run Code Online (Sandbox Code Playgroud)
pot*_*hin 38
你可以使用.inject:
a.inject(:merge)
#=> {:a=>:b, :c=>:d}
Run Code Online (Sandbox Code Playgroud)
它从两个合并的每次迭代中启动一个新的哈希.为了避免这种情况,你可以使用破坏性的:merge!(或者:update,它是相同的):
a.inject(:merge!)
#=> {:a=>:b, :c=>:d}
Run Code Online (Sandbox Code Playgroud)
tok*_*and 21
这两个:
total_hash = hs.reduce({}) { |acc_hash, hash| acc_hash.merge(hash) }
total_hash = hs.reduce({}, :merge)
Run Code Online (Sandbox Code Playgroud)
请注意,Hash#merge在每次迭代时都会创建一个新哈希,如果要构建一个大哈希,这可能会有问题.在这种情况下,请update改用:
total_hash = hs.reduce({}, :update)
Run Code Online (Sandbox Code Playgroud)
另一种方法是将哈希转换为对,然后构建最终哈希:
total_hash = hs.flat_map(&:to_a).to_h
Run Code Online (Sandbox Code Playgroud)
小智 5
我遇到了这个答案,我想在性能方面比较这两个选项,看看哪个更好:
a.reduce Hash.new, :mergea.inject(:merge)使用 ruby 基准测试模块,结果表明选项 (2)a.inject(:merge)更快。
用于比较的代码:
require 'benchmark'
input = [{b: "c"}, {e: "f"}, {h: "i"}, {k: "l"}]
n = 50_000
Benchmark.bm do |benchmark|
benchmark.report("reduce") do
n.times do
input.reduce Hash.new, :merge
end
end
benchmark.report("inject") do
n.times do
input.inject(:merge)
end
end
end
Run Code Online (Sandbox Code Playgroud)
结果是
user system total real
reduce 0.125098 0.003690 0.128788 ( 0.129617)
inject 0.078262 0.001439 0.079701 ( 0.080383)
Run Code Online (Sandbox Code Playgroud)