Questions from a Ruby Newbie (file io and data structures)

I’ve decided on a small project to attempt to learn Ruby beyond just flipping
through the book. By the way, I can’t say enough good things about the pickaxe
book. I picked it up in spite having the electronic version.

I would like to read in a tab (or comma) delimited text file one line or one
item at a time. The input file might look like this:

col1,col2,col3
a,b,c
d,e,f
g,h
j

Note that there is not the same amount of data in each column. It could vary.

What is the best way to read this in from a file? When I’m done I would like to
have all the items in col1 in an array, all the items in col2 in an array, and
so on.

I’m sure this is a rudimentary task, but I would like to see the most elegant
ways in which Ruby permits something like this to be done.

Any other thoughts very much appreciated!

Thanks very much in advance!
Christopher

Christopher J. Meisenzahl CPS, CSTE
Senior Software Testing Consultant
Spherion
christopher.j.meisenzahl@citicorp.com

Hi –

I would like to read in a tab (or comma) delimited text file one line or one
item at a time. The input file might look like this:

col1,col2,col3
a,b,c
d,e,f
g,h
j

Note that there is not the same amount of data in each column. It could vary.

What is the best way to read this in from a file? When I’m done I would like to
have all the items in col1 in an array, all the items in col2 in an array, and
so on.

I’m sure this is a rudimentary task, but I would like to see the most elegant
ways in which Ruby permits something like this to be done.

Any other thoughts very much appreciated!

Here’s a way to do this with the Matrix class. (It assumes
that there are no commas other than the field separators.)

require ‘matrix’
fh = File.open(“filename”,“r”)

m = Matrix[ *
Matrix[ *
fh.readlines.map {|l| l.chomp.split(‘,’) }
].column_vectors
]

The idea is to create a first matrix, based on the splitting of
lines on commas, and then to create a second matrix whose vectors
are the column vectors (i.e., rotated) of the first matrix.

This leaves you with a matrix, made up of Vectors, where each vector
is padded with nils if it’s shorter than whatever the longest one is.
For your sample data:

Matrix[Vector[“col1”, “a”, “d”, “g”, “j”], Vector[“col2”, “b”, “e”,
“h”, nil], Vector[“col3”, “c”, “f”, nil, nil]]

David

···

On Tue, 28 Jan 2003 christopher.j.meisenzahl@citicorp.com wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

I haven’t tested, but it should work.

a = []
IO.foreach { |l| l.split(",").each_with_index{ |s,i| (a[i] ||= []) << s } }

Hi –

···

On Tue, 28 Jan 2003 dblack@candle.superlink.net wrote:

require ‘matrix’
fh = File.open(“filename”,“r”)

m = Matrix[ *
Matrix[ *
fh.readlines.map {|l| l.chomp.split(‘,’) }
].column_vectors
]

Ummm, or:

m = Matrix[ *
fh.readlines.map {|l| l.chomp.split(‘,’) }
].transpose

(Thanks to Martin DeMello for pointing this out.)

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav