Build objects from csv, using column headers as attributes

I have a bunch of csvs for schools that i need to build School objects out of and save. The format and arrangement of columns is different between them, but they all use the same column headers strings to represent the same thing. In other words, the order of columns is different and some have more than others. But they all have "Name" to represent the name of the school.

For example (the real data is tab-separated but i've used spaces here for clarity):

file_a.csv Name Type Size Fake Hill Secondary 450 Brook Street Primary 300

file_b Size Name 450 Notting Hill 200 Camden Street

is there an easy way to pull the data in, using the column headers to decide what attribute is being set by each number? So, that i could import from a bunch of files without having to manually associate the column index with what attribute it is setting, as long as the column names are consistent?

thanks max

Max, first of all, this is not a csv file.. but if you are willing to make it a real csv file then you can do something like the following:

#!/usr/bin/env ruby

schools = ARGV.each do |f_name|   File.open(f_name) do |f|     headers = f.gets.chomp.split(/\s*,\s+/)     while(line = f.gets) do       schools << [headers, line.chomp.split(/\s*,\s*/)].transpose.inject({}) do |h, pair|         h[pair.first] = pair.last         h       end     end   end end p schools

which gives:

./combine file_a.csv file_b.csv [{"Name"=>"Fake Hill", "Size"=>"450", "Type"=>"Secondary"}, {"Name"=>"Brook Street", "Size"=>"300", "Type"=>"Primary"}, {"Name"=>"Notting Hill", "Size"=>"450"}, {"Name"=>"Camden Street", "Size"=>"200"}]

hth

ilan

Max Williams wrote:

Thanks Ilan

I know it's not comma-separated so i probably shouldn't have called it a csv. I tend to use tabs instead of commas but still call the file a csv, sorry. tsv?

Anyway, your solution is a little more elegant than what i came up with, so i'm not posting mine up :slight_smile: thanks! max