將CSV文件作為每一行的屬性來分析。

[英]Parse CSV file with header fields as attributes for each row


I would like to parse a CSV file so that each row is treated like an object with the header-row being the names of the attributes in the object. I could write this, but I'm sure its already out there.

我想要解析一個CSV文件,以便將每一行都當作對象來處理,標題行是對象中屬性的名稱。我可以寫出來,但我肯定它已經寫出來了。

Here is my CSV input:

這是我的CSV輸入:

"foo","bar","baz"
1,2,3
"blah",7,"blam"
4,5,6

The code would look something like this:

代碼是這樣的:

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

With Ruby's CSV module I believe I can only access the fields by index. I think the above code would be a bit more readable. Any ideas?

使用Ruby的CSV模塊,我相信我只能通過索引訪問字段。我認為上面的代碼更容易讀。什么好主意嗎?

5 个解决方案

#1


93  

Using Ruby 1.9 and above, you can get a an indexable object:

使用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

It's not dot syntax but it is much nicer to work with than numeric indexes.

它不是點語法,但比數字索引更好用。

As an aside, for Ruby 1.8.x FasterCSV is what you need to use the above syntax.

順便提一下Ruby 1.8。您需要使用上述語法的是x FasterCSV。

#2


26  

Here is an example of the symbolic syntax using Ruby 1.9. In the examples below, the code reads a CSV file named data.csv from Rails db directory.

下面是一個使用Ruby 1.9的符號語法示例。在下面的示例中,代碼讀取一個名為data的CSV文件。來自Rails db目錄的csv。

:headers => true treats the first row as a header instead of a data row. :header_converters => :symbolize parameter then converts each cell in the header row into Ruby symbol.

:header => true將第一行作為標題,而不是數據行。:header_converters =>:符號化參數,然后將標題行中的每個單元格轉換為Ruby符號。

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

In Ruby 1.8:

在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

Based on the CSV provided by the Poul (the StackOverflow asker), the output from the example code above will be:

基於Poul (StackOverflow asker)提供的CSV,上面示例代碼的輸出為:

1,2,3
blah,7,blam
4,5,6

Depending on the characters used in the headers of the CSV file, it may be necessary to output the headers in order to see how CSV (FasterCSV) converted the string headers to symbols. You can output the array of headers from within the CSV.foreach.

根據CSV文件頭中使用的字符,可能需要輸出頭,以便查看CSV (FasterCSV)如何將字符串頭轉換為符號。您可以從CSV.foreach中輸出頭部數組。

row.headers

#3


2  

Although I am pretty late to the discussion, a few months ago I started a "CSV to object mapper" at https://github.com/vicentereig/virgola.

雖然我很晚才開始討論,但是幾個月前我在https://github.com/vicentereig/virgola上啟動了一個“CSV to object mapper”。

Given your CSV contents, mapping them to an array of FooBar objects is pretty straightforward:

考慮到CSV內容,將它們映射到FooBar對象數組非常簡單:

"foo","bar","baz"
1,2,3
"blah",7,"blam"
4,5,6
require 'virgola'

class FooBar
  include Virgola

  attribute :foo
  attribute :bar
  attribute :baz
end

csv = <<CSV
"foo","bar","baz"
1,2,3
"blah",7,"blam"
4,5,6
CSV

foo_bars = FooBar.parse(csv).all
foo_bars.each { |foo_bar| puts foo_bar.foo, foo_bar.bar, foo_bar.baz }

#4


1  

Easy to get a hash in Ruby 2.3:

在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

#5


-1  

Since I hit this question with some frequency:

因為我用了一些頻率來回答這個問題:

array_of_hashmaps = CSV.read("path/to/file.csv", headers: true)
puts array_of_hashmaps.first["foo"] # 1

This is the non-block version, when you want to slurp the whole file.

這是非塊版本,當您想要刪除整個文件時。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2010/09/15/72f8d0b32f373924fb859282949eb541.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com