ruby nested hash creation
hi I am getting data from a database to create some graphs. I am getting back ~6000+ entries that all have a Type, Data, Month
associated with them. I would like to combine these all into one data structure so that I can take advantage of a Hashes nature of no duplicate keys
to combine the data.
Example: I have output like..
'Component', 4.1167, 'June'
'Component', 3.2167, 'June'
'Component', 4.8667, 'June'
'Component', 3.3833, 'June'
I want to make a nested hash that looks like:
开发者_开发知识库{'Component' => {'June' => '15.5834'}} #where all of the data gets added
The Data comes back to my program as 3 parallel arrays.
This way I can go through all of the data, accumulate it and allow the nature of the hash to remove the duplicates for my labels.
Is this possible in any way?
Thanks Hunter
Depending on how you're getting the data back from the database, you'd be looking at something similar to this...
my_hash = {}
a1, a2, a3 = get_database_result #whatever you call here
a1.each_with_index do |component,i|
month = a3[i]
val = a2[i]
month_hash = my_hash[component] #get the month has for the component
if month_hash.nil? #if it doesn't exist, create it
month_hash = {}
my_hash[component] = month_hash
end
num_val = month_hash[month].nil? ? 0 : month_hash[month] #find the existing numeric value or create a zero
num_val += val #increment by database value
month_hash[month] = num_val #insert the value
end
my_hash #return my_hash
If your individual line items there are themselves hash-like objects with column names, as they would be if they were ActiveRecord instances, then the following code will merge them into your desired final hash. This is a standalone example.
@result = {}
def f x
@result.merge!({ x[:c] => { x[:m] => x[:v] }}) do |k, o, n|
o.merge!(n) do |k, o, n|
o + n
end
end
end
f :c => 'Component', :v => 4.1167, :m => 'June'
f :c => 'Component', :v => 3.2167, :m => 'June'
f :c => 'Component', :v => 4.8667, :m => 'June'
f :c => 'Component', :v => 3.3833, :m => 'June'
p @result
Update: Aha, parallel arrays? Well, you could just change the merge calls to:
f :c => components[i], :v => values[i], :m => months[i]
精彩评论