哈希数组散列(Array of hashes to hash)

2019-06-25 07:45发布

例如,我有单个散列的阵列

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

什么是将其转换成这种方式吗?

{a: :b, c: :d}

Answer 1:

您可以使用

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}


Answer 2:

您可以使用.inject

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

示范

从而启动一个新的哈希在每次迭代从二者的合并。 为了避免这种情况,你可以使用破坏性:merge! (或:update ,这是相同的):

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

示范



Answer 3:

这两个:

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


Answer 4:

试试这个

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


Answer 5:

只要使用

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


Answer 6:

我碰到这个答案,我想这两个选项比较在性能方面,看看哪一个比较好:

  1. a.reduce Hash.new, :merge
  2. a.inject(:merge)

使用红宝石基准模块,事实证明,选项(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)


文章来源: Array of hashes to hash
标签: ruby arrays hash