0

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

2 Answers 2

2

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
Sign up to request clarification or add additional context in comments.

3 Comments

the data comes back as three parallel arrays, thanks Ill give this a shot
What I end up with when I do this is {'Component' => { nil => 'value'}} for some reason the Month doesnt appear
Can you debug and confirm that both the month & val variables are being set to what you're expecting in the first two lines within the loop? (lines 4 & 5 in the code above)
2

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]

2 Comments

Thanks for the idea, my classes dont inherit from ActiveRecord though. I am using the mysql command line to generate XML files. So I am just parsing those instead of doing the native ruby db calls
I see, though it doesn't really matter. f(x) will take a hash which represents a single line of your data with an arbitrary component name and merge it as you outlined.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.