如何将哈希数组添加到 csv 文件中?

How to add an array of hashes into a csv file?

我发现 this code 很适合我,我把它改成了这个:

def write_in_file(file_name, hash)
    column_names = hash.first.keys
    s=CSV.generate do |csv|
        csv << column_names
        hash.each do |x|
            csv << x.values
        end
    end
File.write("#{file_name}.csv", s)
end

这是我的哈希数组的样子:

[
  {:Name => "John", :Age => 26, :Country => America},
  {:Name => "Ivan", :Age => 34, :Country => Russia},
  {:Name => "Pablo", :Age => 20, :Country => Columbia}
]

但问题是,每次我调用此方法时,它都会重写整个文件。如果我想保存此 headers 并在每次迭代中添加新信息,如何更改它?

您可以使用 mode: 'a' 附加到现有文件:(参见 open modes

File.write("#{file_name}.csv", s, mode: 'a')

要仅在第一个 运行 上写入 header,您可以检查该文件是否存在。此外,您应该使用固定的 header 并按特定顺序获取哈希值,例如:

CSV.generate do |csv|
  csv << %w[Name Age Country] unless File.exist?("#{file_name}.csv")

  hash.each do |x|
    csv << x.values_at(:Name, :Age, :Country)
  end
end

File.write("#{file_name}.csv", s, mode: 'a')

还有 CSV.open 可以为您创建文件:

CSV.open("#{file_name}.csv", 'a') do |csv|
  csv << %w[Name Age Country] if csv.stat.zero?

  hash.each do |x|
    csv << x.values_at(:Name, :Age, :Country)
  end
end

由于执行块时文件将始终存在,因此需要更改 header 检查: csv.stat returns 文件的 File::Stat and zero? 确定文件是否存在是空的。