开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜