3

我无法理解 FasterCSV 中的 :header_converters 和 :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 我不理解转换器参数中的 :symbol 和 :all 。

4

3 回答 3

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]并且它会返回字符串值“9”,它将改为返回整数值 9。

标头转换器改变了标头用于索引行的方式。例如,如果做这样的事情:

FastCSV.foreach(some_file, :header_converters => :downcase) do |row|

您可以将标题为“Some Header”的列索引为row['some header'].

如果你:symbol改用它,你会用row[:some_header]. 符号将标题名称小写,用下划线替换空格,并删除 az、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
于 2009-06-02T17:41:36.037 回答
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
于 2016-07-16T15:54:39.407 回答
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

希望这可以帮助!

于 2017-11-17T18:54:05.097 回答