CSV processing with1.9.2 - Multiple Rows being returned as a single array when using options hash
We have just started using Ruby 1.9.2 so we are now using CSV as opposed to FasterCSV (well, we are still using FasterCSV but you know what I mean).
I cant get the code in example 2 below to ignore the header row using options. When I add ANY options to CSV.foreach it merges the entire csv file and all its rows into a single array as opposedd to an array per row. Working example below:
The following code works fine for me (both cases i am using the same file:
CSV.foreach(csv_import.path) do |row_data|
puts row_data.inspect
end
The result is:
["a", "b", "c", "d", "e", "f", "g", "h"]
["1", "1", "1", "1", "1", "1", "1", "1"]
["2", "2", "2", "2", "2", "2", "2", "2"]
PERFECT! thats what I want except I want to ignore ["a", "b", "c", "d", "e", "f", "g", "h"]
So now I write the code:
CSV.foreach(csv_import.path, :headers => true) do |row_data|
puts row_data.inspect
end
The result is 1 single row:
["a", "b", "c", "d", "e", "f", "g", "h\n1", "1", "1", "1", "1", "1", "1", "1\n2", "2", "2", "2", "2", "2", "2", "2"]
Im sure I have stuffed up something in the options Hash, but I dont know what it is? I have tried strings values, string keys, wrapping the options with {}, but to no avail. I have tried row_sep ="\n" also.
I am a RoR newbie, can anyone shed some light on what error I am making here?
Thanks for the response Z开发者_JAVA技巧iggy, but i had no luck. It appears CSV.foreach is returning and Array for me? Would JRuby have an affect:
This is my version
jruby 1.6.0 (ruby 1.9.2 patchlevel 136) (2011-03-15 f3b6154) (Java HotSpot(TM) 6 4-Bit Server VM 1.6.0_24) [Windows 7-amd64-java]
I tried your code and got the following:
CSV.foreach(csv_import.path) do |row_data|
puts row_data.class
puts row_data.length
end
output:
Array 8 Array 8 Array 8
CSV.foreach(csv_import.path, :headers => :first_row, :return_headers => false) do |row_data|
puts row_data.class
puts row_data.length
end
output:
Array 22
I know its a simple workaround to ignore the headers programmatically, just wanted to know if I was using the library incorrectly.
I think you need to use :return_headers
option instead of :headers
. According to CSV's RDOC :headers => true
will make first row from data set a header. So you might want to specify first that the first line is the header and that you want to skip the header. The correct variant of your example should look like this:
CSV.foreach('test.csv', :headers => :first_row, :return_headers => false) do |row_data|
puts row_data.to_s
end
Each row_data object is a CSV::Row object. Since I didn't know which format you've wanted I've used to_s
as example.
Here's the content of my 'test.csv' file: a,b,c,d,e,f,g,h 1,1,1,1,1,1,1,1 2,2,2,2,2,2,2,2
And if I do this
CSV.foreach('test.csv', :headers => :first_row, :return_headers => false) do |row_data|
puts row_data.class
puts row_data.length
end
I'll get
CSV::Row
8
CSV::Row
8
P.S. I'm also using require 'csv'
before the code. And my build is ruby 1.9.2p136 (2010-12-25) [i386-mingw32]
Good luck!
This question looks like it's been abandoned, but:
Because he was in the middle of a transition between ruby versions, I suspect that op's problem was his ruby version. In other words, he was actually using an old version of ruby, meaning that he was using the old CSV library rather than FasterCSV. The old CSV library has exactly the behavior described when you pass in :headers => true.
To check ruby version:
> ruby --version
精彩评论