# Build objects from csv, using column headers as attributes

**URL:** <https://www.ruby-forum.com/t/build-objects-from-csv-using-column-headers-as-attributes/148128>\
**Category:** Rails\
**Created:** [September 9, 2008, 5:09pm UTC](https://www.ruby-forum.com/t/build-objects-from-csv-using-column-headers-as-attributes/148128 "2008-09-09T17:09:09Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [September 9, 2008, 5:09pm UTC](https://www.ruby-forum.com/t/build-objects-from-csv-using-column-headers-as-attributes/148128/1 "2008-09-09T17:09:09Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [September 9, 2008, 10:59pm UTC](https://www.ruby-forum.com/t/build-objects-from-csv-using-column-headers-as-attributes/148128/2 "2008-09-09T22:59:46Z")

</div>

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 W. wrote:

> file\_a.csv  
> Name Type Size  
> Fake Hill Secondary 450  
> Brook Street Primary 300
> 
> file\_b  
> Size Name  
> 450 Notting Hill  
> 200 Camden Street

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [September 10, 2008, 10:59am UTC](https://www.ruby-forum.com/t/build-objects-from-csv-using-column-headers-as-attributes/148128/3 "2008-09-10T10:59:55Z")

</div>

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 🙂 thanks!  
max
