我尝试使用ruby csv lib解析csv文件,但该文件有两列具有相同的标题文本。可以访问列:column
,即row[:column_1]
和row[:column_2]
或row[:column][0]
和row[:column][1]
,还是应该使用索引来访问它?
谢谢
答案 0 :(得分:1)
如果您有重复的标题,那么row [:column]将返回第一个值。
您必须使用索引进行迭代。
require 'csv'
filename = "/path/to/csv"
csv = CSV.table(filename, {:headers => :first_row})
headers = csv.headers
csv.each_with_index do |row, i|
(0...headers.length).each do |j|
column_header = headers[j]
column_value = row[j]
puts " Row #{i}: Header '#{column_header}' has value '#{column_value}'"
end
end
答案 1 :(得分:0)
您可以使用索引:
require 'csv'
data = <<data
a,b,c,b
1,2,3,4
9,8,7,6
data
csv = CSV.new(data, :col_sep => ',', :headers => true)
csv.each do |row|
puts "b: %s, 1: %s, 3: %s" % [row['b'],row[1], row[3]]
end
注意,数字从0开始。
您还可以使用其他方法扩展行对象:
require 'csv'
class CSV::Row
def b_1; self[1]; end
def b_2; self[3]; end
end
data = <<data
a,b,c,b
1,2,3,4
9,8,7,6
data
csv = CSV.new(data, :col_sep => ',', :headers => true)
csv.each do |row|
puts row.b_1
puts row.b_2
end
此逻辑将为所有行对象(也用于完整的不同CSV文件)定义方法b_1
和b_2
。所以这可能是一个小脚本的解决方案,但我不会在更大的项目中使用它。
您也可以在每个循环中定义方法:
require 'csv'
data = <<data
a,b,c,b
1,2,3,4
9,8,7,6
data
csv = CSV.new(data, :col_sep => ',', :headers => true)
csv.each do |row|
class << row
def b_1; self[1]; end
def b_2; self[3]; end
end
puts row.b_1
puts row.b_2
end
如果你有多个循环,你也可以定义一个模块并扩展每一行:
require 'csv'
module RowExtension
def b_1; self[1]; end
def b_2; self[3]; end
end
data = <<data
a,b,c,b
1,2,3,4
9,8,7,6
data
csv = CSV.new(data, :col_sep => ',', :headers => true)
csv.each do |row|
row.extend RowExtension
puts row.b_1
puts row.b_2
end
也许还有可能扩展CSV类以返回特定的row-element。但这超出了我的实际知识。
另一种解决方案是使用headers-option。 headers-options定义标题字段,因此您可以定义自己的标题:
require 'csv'
data = <<data
a,b,c,b
1,2,3,4
9,8,7,6
data
csv = CSV.new(data, :col_sep => ',', :headers => %w{a b_1 c b_2})
csv.each do |row|
puts row['b_1']
puts row['b_2']
end
现在你必须忽略第一行(旧标题行)。
答案 2 :(得分:0)
我不确定你的问题。但是,如果您想以表格格式访问CSV数据,只需使用CSV :: Table类,如下所示
csv = CSV.parse('csv_string')
csv_array = csv.transpose
Here是关于方法的更多信息
如果要在解析数据后以列为基础访问数据,只需按以下方式转置数组
ocpu.rpc()