我无法理解FasterCSV中的:header_converters和:转换器。基本上,我想要做的就是将列标题更改为适当的列名。
类似的东西:
FasterCSV.foreach(csv_file, {:headers => true, :return_headers => false, :header_converters => :symbol, :converters => :all} ) do |row|
puts row[:some_column_header] # Would be "Some Column Header" in the csv file.
execpt我不理解:符号和:全部在转换器参数中。
答案 0 :(得分:9)
:all
转换器意味着它会尝试所有内置转换器,特别是:
:integer: Converts any field Integer() accepts.
:float: Converts any field Float() accepts.
:date: Converts any field Date::parse() accepts.
:date_time: Converts any field DateTime::parse() accepts.
基本上,这意味着它会尝试将任何字段转换为这些值(如果可能),而不是将它们保留为字符串。因此,如果你执行row[i]
并且它将返回String值'9',它将返回一个Integer值9。
标头转换器会更改标头用于索引行的方式。例如,如果做这样的事情:
FastCSV.foreach(some_file, :header_converters => :downcase) do |row|
您可以使用标题“Some Header”将列编入索引为row['some header']
。
如果您使用的是:symbol
,则可以使用row[:some_header]
对其进行索引。符号下标头名称,用下划线替换空格,并删除a-z,0-9和_
以外的字符。它很有用,因为符号的比较远比字符串的比较快。
如果您想使用row['Some Header']
索引列,那么就不要提供任何:header_converter
选项。
在回复你的评论时,我会害怕headers_convert不会做你想做的事。它不会更改标题行的值,只是它们如何用作索引。相反,您必须使用:return_headers
选项,检测标题行并进行更改。要更改文件并再次将其写出,您可以使用以下内容:
require 'fastercsv'
input = File.open 'original.csv', 'r'
output = File.open 'modified.csv', 'w'
FasterCSV.filter input, output, :headers => true, :write_headers => true, :return_headers => true do |row|
change_headers(row) if row.header_row?
end
input.close
output.close
如果您需要完全替换原始文件,请在执行上述操作后添加以下行:
FileUtils.mv 'modified.csv', 'original.csv', :force => true
答案 1 :(得分:1)
我找到了解决这个问题的简单方法。 FasterCSV库工作得很好。我确信在创建帖子到现在之间约7年可能与它有关,但我认为值得注意。
在我看来,在阅读CSV文件时,FasterCSV :header_converters
选项没有详细记录。但是,不是分配符号(header_converters: :symbol
),而是可以分配lambda(header_converters: lambda {...}
)。当CSV库读取文件时,它使用lambda转换标题。然后,可以保存反映已转换标头的新CSV文件。
例如:
options = {
headers: true,
header_converters: lambda { |h| HEADER_MAP.keys.include?(h.to_sym) ? HEADER_MAP[h.to_sym] : h }
}
table = CSV.read(FILE_TO_PROCESS, options)
File.open(PROCESSED_FILE, "w") do |file|
file.write(table.to_csv)
end
答案 2 :(得分:0)
重写CSV文件标题是将导出的CSV文件转换为导入的任何人的常见要求。
我发现以下方法给了我所需要的东西:
lookup_headers = { "old": "new", "cat": "dog" } # The desired header swaps
CSV($>, headers: true, write_headers: true) do |csv_out|
CSV.foreach( ARGV[0],
headers: true,
# the following lambda replaces the header if it is found, leaving it if not...
header_converters: lambda{ |h| lookup_headers[h] || h},
return_headers: true) do |master_row|
if master_row.header_row?
# The headers are now correctly replaced by calling the updated headers
csv_out << master_row.headers
else
csv_out << master_row
end
end
end
希望这有帮助!