使用标题字段解析CSV文件作为每行的属性

Pou*_*oul 63 ruby csv parsing

我想解析一个CSV文件,以便将每一行视为一个对象,其中header-row是对象中属性的名称.我可以写这个,但我确定它已经在那里了.

这是我的CSV输入:

"foo","bar","baz"
1,2,3
"blah",7,"blam"
4,5,6
Run Code Online (Sandbox Code Playgroud)

代码看起来像这样:

CSV.open('my_file.csv','r') do |csv_obj|
  puts csv_obj.foo   #prints 1 the 1st time, "blah" 2nd time, etc
  puts csv.bar       #prints 2 the first time, 7 the 2nd time, etc
end
Run Code Online (Sandbox Code Playgroud)

使用Ruby的CSV模块,我相信我只能通过索引访问字段.我认为上面的代码会更具可读性.有任何想法吗?

Pee*_*lan 111

使用Ruby 1.9及更高版本,您可以获得一个可索引的对象:

CSV.foreach('my_file.csv', :headers => true) do |row|
  puts row['foo'] # prints 1 the 1st time, "blah" 2nd time, etc
  puts row['bar'] # prints 2 the first time, 7 the 2nd time, etc
end
Run Code Online (Sandbox Code Playgroud)

这不是点语法,但它比数字索引更好用.

顺便说一句,对于Ruby 1.8.x ,您需要使用FasterCSV以上语法.

  • 如果你真的想要点语法,你可以`require ostruct`然后抛出一个`row_struct = OpenStruct.new(row.to_h)`的步骤,它会响应`row_struct.foo`。 (2认同)

sca*_*er2 36

以下是使用Ruby 1.9的符号语法示例.在下面的示例中,代码从Rails db目录中读取名为data.csv的CSV文件.

:headers => true将第一行视为标题而不是数据行.:header_converters => :symbolize然后,参数将标题行中的每个单元格转换为Ruby符号.

CSV.foreach("#{Rails.root}/db/data.csv", {:headers => true, :header_converters => :symbol}) do |row|
  puts "#{row[:foo]},#{row[:bar]},#{row[:baz]}"
end
Run Code Online (Sandbox Code Playgroud)

在Ruby 1.8中:

require 'fastercsv'
CSV.foreach("#{Rails.root}/db/data.csv", {:headers => true, :header_converters => :symbol}) do |row|
  puts "#{row[:foo]},#{row[:bar]},#{row[:baz]}"
end
Run Code Online (Sandbox Code Playgroud)

基于Poul(StackOverflow提问者)提供的CSV,上面示例代码的输出将是:

1,2,3
blah,7,blam
4,5,6
Run Code Online (Sandbox Code Playgroud)

根据CSV文件标题中使用的字符,可能需要输出标题以查看CSV(FasterCSV)如何将字符串标题转换为符号.您可以从中输出标题数组CSV.foreach.

row.headers
Run Code Online (Sandbox Code Playgroud)


Yar*_*rin 5

在Ruby 2.3中很容易获得哈希:

CSV.foreach('my_file.csv', headers: true, header_converters: :symbol) do |row|
  puts row.to_h[:foo]
  puts row.to_h[:bar]
end
Run Code Online (Sandbox Code Playgroud)