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