0

What I have is :

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

I wish to convert it to :

{"Key1":{"key2":30,"key3":40}}
1
  • 1
    You hashes are not valid: key: value only works for symbolic keys, you have to use key => value. Commented Oct 15, 2014 at 8:02

2 Answers 2

1

You can merge multiple hashes:

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

Applied to your hash:

hash = {"Key1"=>[{"key2"=>"30"}, {"key3"=>"40"}]}
hash["Key1"] = hash["Key1"].inject(:merge)
hash #=> {"Key1"=>{"key2"=>"30", "key3"=>"40"}}
Sign up to request clarification or add additional context in comments.

Comments

0

I'd prefer Stefan's answer as it looks cleaner. Posting this to just show an another approach:

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

then you can:

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

However, I did benchmarking and results were a bit weird:

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

Result with 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)

Result with 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)

Result with 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)

And I'm not sure why map_and_flatten was faster than with_inject in Ruby 2.1.2.

1 Comment

Your approach doesn't work if a hash contains more than one key-value pair, e.g.: Hash[[{a:1},{b:2,c:3}].map(&:flatten)]. But you could use Hash[array.flat_map(&:to_a)] to solve that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.