views:

76

answers:

1

I have this code here and it works but there has to be a better way.....i need two arrays that look like this

[ 
{
  "Vector Arena - Auckland Central, New Zealand" => { 
    "2010-10-10" => [
       "Enter Sandman", 
       "Unforgiven", 
       "And justice for all"
    ]
  }
},  
{
  "Brisbane Entertainment Centre - Brisbane Qld, Austr..." => { 
    "2010-10-11" => [
      "Enter Sandman"
    ]
  }
}
]

one for the past and one for the upcoming...the problem i have is i am repeating myself and though it works i want to clean it up ...here is my data ..

+1  A: 

Try this:

h = Hash.new {|h1, k1| h1[k1] = Hash.new{|h2, k2| h2[k2] = []}}
result, today = [ h, h.dup], Date.today

Request.find_all_by_artist("Metallica", 
 :select => "DISTINCT venue, showdate, LOWER(song) AS song"
).each do |req|
  idx = req.showdate < today ? 0 : 1
  result[idx][req.venue][req.showdate] << req.song.titlecase
end

Note 1

In the first line I am initializing an hash of hashes. The outer hash creates the inner hash when a non existent key is accessed. An excerpt from Ruby Hash documentation:

If this hash is subsequently accessed by a key that doesn‘t correspond to a hash 
entry, the block will be called with the hash object and the key, and should 
return the default value. It is the block‘s responsibility to store the value in 
the hash if required. 

The inner hash creates and empty array when the non existent date is accessed.

E.g: Construct an hash containing of content as values and date as keys:

Without a default block:

h = {}
list.each do |data|
  h[data.date] = [] unless h[data.date]
  h[data.date] << data.content
end

With a default block

h = Hash.new{|h, k| h[k] = []}
list.each do |data|
  h[data.date] << data.content
end

Second line simply creates an array with two items to hold the past and future data. Since both past and the present stores the data as Hash of Hash of Array, I simply duplicate the value.

Second line can also be written as

result = [ h, h.dup]
today = Date.today
KandadaBoggu
this looks awesome thank you soo much .. though can you explain the first two lines
Matt
i get this though ActiveRecord::MissingAttributeError: missing attribute: song
Matt
Updated my answer take a look.
KandadaBoggu
thanks alot.....only thing i had to change was the ).each do |req|....you forgot the do
Matt
Updated my answer with explanation. Take a look.
KandadaBoggu