Ruby,一个哈希数组,转换为单个hashmap

时间:2014-10-15 07:53:15

标签: ruby hash map key-value

我拥有的是:

{"Key1":[{"key2":"30"},{"key3":"40"}]}

我希望将其转换为:

{"Key1":{"key2":30,"key3":40}}

2 个答案:

答案 0 :(得分:1)

你可以merge多个哈希:

[{foo: 1}, {bar: 2}, {baz: 3}].inject(:merge)
#=> {:foo=>1, :bar=>2, :baz=>3}

应用于您的哈希:

hash = {"Key1"=>[{"key2"=>"30"}, {"key3"=>"40"}]}
hash["Key1"] = hash["Key1"].inject(:merge)
hash #=> {"Key1"=>{"key2"=>"30", "key3"=>"40"}}

答案 1 :(得分:0)

我更喜欢Stefan的回答,因为它看起来更干净。发布此信息只是为了展示另一种方法:

hash = {"key1" => [{"key2" => "30"},{"key3" => "40"}]}

然后你可以:

hash["key1"] = Hash[hash["key1"].flat_map(&:to_a)]
#=> {"key1"=>{"key2"=>"30", "key3"=>"40"}}

但是,我做了基准测试,结果有点奇怪:

require 'benchmark'

def with_inject
  hash = {"Key1"=>[{"key2"=>"30"}, {"key3"=>"40"}]}
  hash["Key1"] = hash["Key1"].inject(:merge)
  hash
end

def map_and_flatten
  hash = {"key1" => [{"key2" => "30"},{"key3" => "40"}]}
  hash["key1"] = Hash[hash["key1"].flat_map(&:to_a)]
  hash
end

n = 500000
Benchmark.bm(50) do |x|
  x.report("with_inject     "){ n.times { with_inject } }
  x.report("map_and_flatten "){ n.times { map_and_flatten } }
end

Ruby-1.9.2-p290的结果 -

                        user      system      total        real
with_inject           2.000000   0.000000   2.000000 (  2.008612)
map_and_flatten       2.290000   0.010000   2.300000 (  2.293664)

Ruby-2.0.0-p353的结果 -

                        user      system      total        real
with_inject            2.350000   0.020000   2.370000 (  2.366092)
map_and_flatten        2.420000   0.000000   2.420000 (  2.419962)

Ruby-2-1-2-p95的结果 -

                        user      system      total        real
with_inject            2.180000   0.010000   2.190000 (  2.198437)
map_and_flatten        2.100000   0.000000   2.100000 (  2.104745)

我不确定为什么map_and_flatten比Ruby 2.1.2中的with_inject更快。