Hash key with multiple values

Hi ,
i have the hash result is

puts @results
[{x=>"i8"}, {y=>"i58"}, {y=>"i6"}, {y=>"v5"}, {z=>"ci5"}, {z=>"i63"},
{w=>"cie201"}]

from this @results hash ,i want to get new hash like below

puts @conver_results
[{x=>"i8"}, {y=>"i58","i6","v5"}, {z=>"ci5","i63"},  {w=>"cie201"}]

Please help me

Hello,

i have the hash result is

I would rather say that it is an array of hashes that you want to
transform into an hash of arrays.

Please help me

First, you have to get the keys that will be in the resulting hash,
for example using inject (that here merge all the hashes into one big
hashes but loosing multiple entries of the same key):

arr = [{x=>“i8”}, {y=>“i58”}, {y=>“i6”}, {y=>“v5”}, {z=>“ci5”},
{z=>“i63”}, {w=>“cie201”}]
keys = arr.inject {|hash,h| hash.merge(h)}.keys
p keys

Then iterate over the keys and populate the resulting hash by
selecting all the adequate values (that is those whose call don’t
answer nil) and collecting them:

result_hash = {}
keys.each do |k|
result_hash[k] = arr.select {|h| h[k]}.collect {|h| h[k]}
end
p result_hash

Hope this helps.

Lucky Nl wrote:

puts @results
[{x=>“i8”}, {y=>“i58”}, {y=>“i6”}, {y=>“v5”}, {z=>“ci5”}, {z=>“i63”},
{w=>“cie201”}]
[/code]
from this @results hash ,i want to get new hash like below

puts @conver_results
> [{x=>"i8"}, {y=>"i58","i6","v5"}, {z=>"ci5","i63"},  {w=>"cie201"}]

Note that {z=>“ci5”,“i63”} is not valid hash syntax. But you can have
{“z”=>[“ci5”,“i63”]}

@conver_results = Hash.new { |h,k| h[k] = [] }
@results.each { |h| h.each { |k,v| @conver_results[k] << v } }

The first line makes a Hash whose elements are automatically an empty
array if not already created. The second iterates over your original
hashes and adds to the values array for each key.

Another way:

@conver_results = {}
@results.heac { |h| h.each { |k,v|
@conver_results[k] ||= []
@conver_results[k] << v
} }

BTW, the structure you have with an array of hashes, each hash with a
single k/v pair, is unusual:

@results = [{“x”=>“i8”}, {“y”=>“i58”}, {“y”=>“i6”}, {“y”=>“v5”},
{“z”=>“ci5”}, {“z”=>“i63”}, {“w”=>“cie201”}]

It would be more usual to have 2-element arrays for the k/v pairs:

@results = [[“x”,“i8”], [“y”,“i58”], [“y”,“i6”], [“y”,“v5”],
[“z”,“ci5”], [“z”,“i63”], [“w”,“cie201”]]

which in turn simplifies the processing:

@conver_results = Hash.new { |h,k| h[k] = [] }
@results.each { |k,v| @conver_results[k] << v }

On 04/03/2010 12:24 PM, Lucky Nl wrote:

@results = [{“x”=>“i8”}, {“y”=>“i58”}, {“y”=>“i6”}, {“y”=>“v5”},
{“z”=>“ci5”}, {“z”=>“i63”}, {“w”=>“cie201”}]

so i want the order is

{ “x”=>[“i8”], “y”=>[“i58”, “i6”, “v5”], “z”=>[“ci5”,
“i63”],“w”=>[“cie201”]}

In Ruby 1.9 Hash maintains insertion order so you should get what you
expect. But generally hashes are not ordered. If you want to enforce a
particular ordering then you need to explicitly sort.

Kind regards

robert

Hi , thankq to all,
every solution is working

but the problem is am not getting in order means

getting result is
{“w”=>[“cie201”], “x”=>[“i8”], “y”=>[“i58”, “i6”, “v5”], “z”=>[“ci5”,
“i63”]}

but actual order of the elements placed is
@results = [{“x”=>“i8”}, {“y”=>“i58”}, {“y”=>“i6”}, {“y”=>“v5”},
{“z”=>“ci5”}, {“z”=>“i63”}, {“w”=>“cie201”}]

so i want the order is

{ “x”=>[“i8”], “y”=>[“i58”, “i6”, “v5”], “z”=>[“ci5”,
“i63”],“w”=>[“cie201”]}

Hi thanks for all your suggetions. my problem solved by using sort
method

HI,
Can you suggest how to sort explicitly,
actually in my requirement keys are dates for exmaple

{ “2010-04-03”=>[“i8”], “2010-04-04”=>[“i8f”],“2010-04-04”=>[“wi8”]}