1

I'm opening CSV using Ruby:

CSV.foreach(file_name, "r+") do |row|
  next if row[0] == 'id'
  update_row! row    
end

and I don't really care about headers row.

I don't like next if row[1] == 'id' inside loop. Is there anyway to tell CSV to skip headers row and just iterate through rows with data ?

I assume provided CSVs always have a header row.

NM Pennypacker
  • 6,704
  • 11
  • 36
  • 38
Filip Bartuzi
  • 5,711
  • 7
  • 54
  • 102

3 Answers3

3

There are a few ways you could handle this. The simplest method would be to pass the {headers: true} option to your loop:

CSV.foreach(file_name, headers: true) do |row|
  update_row! row    
end

Notice how there is no mode specified - this is because according to the documentation, CSV::foreach takes only the file and options hash as its arguments (as opposed to, say, CSV::open, which does allow one to specify mode.

Alternatively, you could read the data into an array (rather than using foreach), and shift the array before iterating over it:

 my_csv= CSV.read(filename)
 my_csv.shift
 my_csv.each do |row|
     update_row! row 
 end
Sculper
  • 756
  • 2
  • 12
  • 24
  • 1
    Don't read data into an array unless you're guaranteed that the file will fit into memory. CSV files can be huge, especially when used to move database tables. It's easy to use `foreach` and still ignore the first row which maintains scalability. [Slurping data, such as using `read` is going to be slower 99% of the time than using `foreach`](http://stackoverflow.com/questions/25189262/why-is-slurping-a-file-bad).. – the Tin Man Aug 26 '15 at 20:05
  • This raises ` `foreach': wrong number of arguments (3 for 1..2) (ArgumentError` – Filip Bartuzi Aug 27 '15 at 10:23
1

According to Ruby doc:

options = {:headers=>true}
CSV.foreach(file_name, options) ...

should suffice.

Tim
  • 2,008
  • 16
  • 22
-1

A simple thing to do that works when reading files line-by-line is:

CSV.foreach(file_name, "r+") do |row|
  next if $. == 1
  update_row! row    
end

$. is a global variable in Ruby that contains the line-number of the file being read.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303