红宝石-要哈希的哈希数组

例如,我有单哈希数组

a = [{a: :b}, {c: :d}]

将其转换为此的最佳方法是什么?

{a: :b, c: :d}
evfwcqcg asked 2019-10-07T20:22:22Z
6个解决方案
108 votes

你可以用

a.reduce Hash.new, :merge

直接产生

{:a=>:b, :c=>:d}

请注意,在发生碰撞的情况下,顺序很重要。 较晚的哈希值会覆盖以前的映射,例如:

[{a: :b}, {c: :d}, {e: :f, a: :g}].reduce Hash.new, :merge   # {:a=>:g, :c=>:d, :e=>:f}
Howard answered 2019-10-07T20:22:41Z
32 votes

您可以使用:merge!

a.inject(:merge)
#=> {:a=>:b, :c=>:d}

示范

这会在合并后的两次迭代中启动新的哈希。 为避免这种情况,可以使用破坏性的:merge!(或:update,这是相同的):

a.inject(:merge!)
#=> {:a=>:b, :c=>:d}

示范

potashin answered 2019-10-07T20:23:19Z
21 votes

这两个:

total_hash = hs.reduce({}) { |acc_hash, hash| acc_hash.merge(hash) }
total_hash = hs.reduce({}, :merge)

请注意,Hash#merge在每次迭代时都会创建一个新的哈希,如果您要构建一个大哈希,则可能会遇到问题。 在这种情况下,请改用update

total_hash = hs.reduce({}, :update)

另一种方法是将散列转换成对,然后构建最终的散列:

total_hash = hs.flat_map(&:to_a).to_h
tokland answered 2019-10-07T20:23:56Z
0 votes

试试这个

a.inject({}){|acc, hash| acc.merge(hash)} #=> {:a=>:b, :c=>:d}
Rahul Patel answered 2019-10-07T20:24:16Z
0 votes

只需使用

a.reduce(:merge)
#=> {:a=>:b, :c=>:d}
Ritesh katare answered 2019-10-07T20:24:35Z
0 votes

我遇到了这个答案,我想从性能上比较这两个选项,以查看哪个更好:

  1. a.reduce Hash.new, :merge
  2. a.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

结果是

       user     system      total        real
reduce  0.125098   0.003690   0.128788 (  0.129617)
inject  0.078262   0.001439   0.079701 (  0.080383)
bigsolom answered 2019-10-07T20:25:33Z
translate from https://stackoverflow.com:/questions/10943909/array-of-hashes-to-hash