开发者

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]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜