On Mon, Jul 15, 2002 at 07:16:45AM +0900, Kurt Euler wrote:
> All-
> 
> Please advise as to how to skip the reading of first line in a file during an iteration.
> 
> I use the following construction to read a line at a time in a text file:
> 
> 	IO.foreach("./control/packages.txt") { |x|
> 		field = x.chop.split('\t')
> 		content2 = content.dup
> 		...etc.
> 
> However, the file that I'm reading from is a tab-delimited text file that I exported from Excel. This Excel file has column titles which, of course, get exported too. (I could add a "while" statement to skip processing of a line if it includes a title line string, but testing with each iteration
> seems too expensive.)
> 
> 
> On a related note, is there a way read in the rows of an Excel file as one would read in the lines of a text file? If so, please advise how. Or, perhaps there's a method for reading an Excel file into a 2D array. Again, please advise.
> 

Let's break this down. First, there are many ways to do what you want.
The method you choose depends on your circumstances. If you exported
as Comma Separated Value (csv), then you could use the csv package.

I have looked at the package, but when it comes to parsing comma/space/tab
separated lines, the parsing is usually so easy, I just roll my own.

Your questions seem to be:
 1. Is there a way to exclude the header line when importing excel (tsv text file).
 2. Can lines of an excell file be read as a text file.
 3. Can an excel file be read into a 2d array.


1. To exclude comment lines I typically do the following:

IO.foreach("file") { |line|
  next if /^#/ =~ line
  <process line here>
}


2. If you are talking about a way to read a binary .xls file, I
don't know of one. And if one existed, I would not use it
since MS can change their propietary format on a whim.

3. If you are talking about how to do this from a csv file,
then it is not too hard. The following would work, but I
am sure we could get many more (from those who love to
golf)

## untested
ary = []
IO.foreach("file") { |line|
  next if /^#/ =~ line
  a = line.strip.split(',')
  ary << a
} 

At this point ary is a 2d array (1d array of row arrays)
but the values are text.

#=> [["1.0", "2.0", "3.0"], ["0.1", "0.2", "0.3"]]

I have found that I don't trust anyone or anything in
most cases, so to convert the following to a numeric
array, I use a to_number function:

## to_number(string) => number_Or_nil
def to_number(s)
  Integer(s) rescue Float(s) rescue nil
end#to_number


Ary can be converted with:

ary.collect! { |row|
  row.collect{ |s| raise unless (n = to_number_s)
    n
  }
}

-- 
Jim Freeze
If only I had something clever to say for my comment...
~