Reversing 2-array axis in Ruby
Recently, I was working on a project that imports some CSV data into a dynamic database table. It needs to sort an array of floats. Along the way coding, I found myself doing something curious:
rows = @table_class.all
rows.each do | row |
key = row.primary_key.to_sym
@matches[key] = []
row.instance_variables.each do | column |
unless ['@id', '@repository','@primary_key','@original_values', '@new_record','@collection', '@updated_at'].include? column
x = row.instance_variable_get(column)
y = column.gsub(/@/, '')
@matches[key] << {:x => x, :y => y}
end
end
@matches[key] = @matches[key].sort_by { |match| match[:y] }
end
@matchesSorting in Ruby! This smells bad. I put the data in a database for this?
The solution
The solution was to reverse the axis of the imported data, thereby enabling MySQL to sort the data for us.
Instead of doing:
n=0
@parsed_file.each do | row |
hash = row2hash(row)
unless @table_class.first(:primary_key => hash[:primary_key])
instance = @table_class.new(hash)
if instance.save
n+=1
GC.start if n%50 == 0
end
end
endWe can parse the file with inversed axis by doing:
values = {}
@parsed_file[0].enum_with_index.map do |primary_key, idx|
if primary_key
pk = primary_key.to_sym
@parsed_file.collect do |row|
if row[0]
values[pk] = {} unless values[pk].is_a?(Hash)
values[pk][row[0].to_sym] = row[idx]
end
end
end
end
n = 0
values.keys.each do |key|
if values[key]
unless @table_class.first(:primary_key => key.to_s)
instance = @table_class.new(values[key])
instance.primary_key = key
if instance.save
n+=1
GC.start if n%50 == 0
end
end
end
endI admit this is totally crazy code, and I don’t expect you to follow along. The rest of the class needed a bit of modifying too, but the first code example above has been simplified to:
@matches[primary_key.to_sym] = @table_class.all(:order => [primary_key.to_sym.desc])Ofcourse this hasn’t hurt performance, either
Trackbacks
Use the following link to trackback from your own site:
http://blog.aczid.nl/trackbacks?article_id=20










