Array of hashes to hash
You may use
a.reduce Hash.new, :merge
which directly yields
{:a=>:b, :c=>:d}
Note that in case of collisions the order is important. Latter hashes override previous mappings, see e.g.:
[{a: :b}, {c: :d}, {e: :f, a: :g}].reduce Hash.new, :merge # {:a=>:g, :c=>:d, :e=>:f}
Convert array of hashes to single hash with values as keys
This should do what you want
countries.each_with_object({}) { |country, h| h[country[:country].to_sym] = country[:cost] }
=> {:england=>12.34, :scotland=>56.78}
Convert array-of-hashes to a hash-of-hashes, indexed by an attribute of the hashes
Ruby <= 2.0
> Hash[api_response.map { |r| [r[:id], r] }]
#=> {1=>{:id=>1, :foo=>"bar"}, 2=>{:id=>2, :foo=>"another bar"}}
However, Hash::[] is pretty ugly and breaks the usual left-to-right OOP flow. That's why Facets proposed Enumerable#mash:
> require 'facets'
> api_response.mash { |r| [r[:id], r] }
#=> {1=>{:id=>1, :foo=>"bar"}, 2=>{:id=>2, :foo=>"another bar"}}
This basic abstraction (convert enumerables to hashes) was asked to be included in Ruby long ago, alas, without luck.
Note that your use case is covered by Active Support: Enumerable#index_by
Ruby >= 2.1
[UPDATE] Still no love for Enumerable#mash
, but now we have Array#to_h. It creates an intermediate array, but it's better than nothing:
> object = api_response.map { |r| [r[:id], r] }.to_h
How can I convert a ruby array of hashes into a single hash?
arr = [{"name"=>"apple", "value"=>"red"},
{"name"=>"banana", "value"=>"yellow"},
{"name"=>"grape", "value"=>"purple"}]
Hash[arr.map { |h| [h["name"].to_sym , h["value"]] }]
#=> {:apple=>"red", :banana=>"yellow", :grape=>"purple"}
With Ruby 2.1+
arr.map { |h| [h["name"].to_sym , h["value"]] }.to_h
#=> {:apple=>"red", :banana=>"yellow", :grape=>"purple"}
Converting an array of hashes to ONE hash in Ruby
I think the key to the solution is Hash[]
, which will create a Hash based on an array of key/values, i.e.
Hash[[["key1", "value1"], ["key2", "value2"]]]
#=> {"key1" => "value1", "key2" => "value2"}
Just add a set of map
, and you have a solution!
result = [
{"id_t"=>["1"], "transcript_t"=>["I am a transcript ONE"]},
{"id_t"=>["2"], "transcript_t"=>["I am a transcript TWO"]},
{"id_t"=>["3"], "transcript_t"=>["I am a transcript THREE"]}
]
Hash[result.map(&:values).map(&:flatten)]
Convert array of hash to single hash in ruby
a.each_with_object({}) {|obj , hash| hash.merge!(Hash[obj[:id], Hash["active_accounts",obj[:active_accounts]]])}
# {5=>{"active_accounts"=>3}, 1=>{"active_accounts"=>6}}
Hope it helps.
Ruby Array of hashes to a Hash
array.each_with_object({}){|e, h| e = e.dup; h[e.delete(:a)] = e}
# => {123=>{:b=>"foo", :c=>"bar"}, 456=>{:b=>"baz", :c=>"qux"}}
If you don't care about side effects:
array.each_with_object({}){|e, h| h[e.delete(:a)] = e}
# => {123=>{:b=>"foo", :c=>"bar"}, 456=>{:b=>"baz", :c=>"qux"}}
How can I transpose array of hashes in ruby
Something like this might do the job:
keys = input.map { |hash| hash['Key'] }.uniq
result = Hash.new { |result, id| result[id] = {} }
input.each { |hash| result[hash['ID']].merge!(hash['Key'] => hash['Value']) }
result.default = nil # optional: remove the default value
result.each do |id, hash|
(keys - hash.keys).each { |key| hash[key] = '' }
hash['ID'] = id
end
result.values
#=> [{"Field A"=>"123", "Field B"=>"333", "Field C"=>"555", "Field D"=>"", "ID"=>"100"},
# {"Field A"=>"789", "Field B"=>"999", "Field D"=>"444", "Field C"=>"", "ID"=>"200"}]
If you're certain values are never falsy you can replace:
(keys - hash.keys).each { |key| hash[key] = '' }
# with
keys.each { |key| hash[key] ||= '' }
I first create a hash result
to save the resulting hashes, I set the value to defaults to a new hash. Then I get the correct hash based upon ID and merge the key-value pairs into the hash. Lastly I add the missing keys to the hashes and set their values to an empty string and add the ID under which the hash is saved to the hash.
note: If your
input
array contains duplicate key-value pairs, the last one will be used. For example, say both{"ID"=>"100", "Key"=>"Field A", "Value"=>"123"}
and{"ID"=>"100", "Key"=>"Field A", "Value"=>"456"}
are present. Then"Field A" => "456"
will be set, since it's the latter of the two.
Convert hash to array of hashes
Leveraging Array#transpose and Array#to_h
keys = list.keys
list.values.transpose.map { |v| keys.zip(v).to_h }
Convert array of hashes to array
a=[{:code=>"404"}, {:code=>"302"}, {:code=>"200"}]
puts a.map{|x|x.values}.flatten.inspect
output
["404", "302", "200"]
Related Topics
Why Does Hash.New({}) Hide Hash Members
Bundle Install/Error in Installing Libv8 (3.3.10.4) on Rails (Running on Lion)
Thor & Yaml Outputting as Binary
Understanding Ruby Splat in Ranges and Arrays
Rails Calculate Date Range in Months
Why Would You Use a !! Operator
How to Shorten a Uuid to a Specific Length
Getting Error "Exceeded Available Parameter Key Space"
What's the Purpose of Tainting Ruby Objects
How to Use Variables in a Yaml File
JSON::Parsererror: 757: Unexpected Token at '{
Ruby: Escaping Special Characters in a String
Serialize Array with Strong_Parameters
Use Windows or Linux to Start Work with Ruby on Rails
How to Round a Float to a Specified Number of Significant Digits in Ruby