Jan
Jan

Reputation: 16074

Remove surrounding Array and deliver one hash in Ruby

I have an Array as result of a query:

{"name"=>[{"en"=>"Title"}, {"de"=>"Titel"}]}

I wanna get the hashes of this Array and concat them into one Hash

So that my result is like that.

{"en"=>"Title", "de"=>"Titel"}

Thank you

Upvotes: 1

Views: 202

Answers (2)

toro2k
toro2k

Reputation: 19230

You can use the Enumerable#reduce and the Hash#merge! methods:

hash = {"name"=>[{"en"=>"Title"}, {"de"=>"Titel"}]}
hash['name'].reduce({}) { |result, h| result.merge!(h) }
# => {"en"=>"Title", "de"=>"Titel"}

Or in a slightly more efficient way using the Enumerable#each_with_object method:

hash['name'].each_with_object({}) { |h, result| result.merge!(h) }
# => {"en"=>"Title", "de"=>"Titel"}

The comparison:

require 'fruity'

names = [{"en"=>"Title"}, {"de"=>"Titel"}]

compare do   
  reduce do
    names.reduce({}) { |result, h| result.merge!(h) }
  end

  each_with_object do
    names.each_with_object({}) { |h, result| result.merge!(h) }
  end 
end

The result:

Running each test 1024 times. Test will take about 1 second.
each_with_object is faster than reduce by 30.000000000000004% ± 10.0%

Upvotes: 1

Agis
Agis

Reputation: 33626

Simply do:

hash = {"name"=>[{"en"=>"Title"}, {"de"=>"Titel"}]}
hash["name"].reduce(:merge) # => {"en"=>"Title", "de"=>"Titel"}

Upvotes: 1

Related Questions