Ruby - CSV的哈希数组

时间:2017-06-27 08:04:39

标签: arrays ruby csv hash

我收集了一些数据并将其保存为以下形式的哈希数组:

info = [
  {'Name' => 'Alex', 'Tel' => 999, 'E-mail' => "bla@bla.com"},
  {'Name' => 'Ali', 'Tel' => 995, 'E-mail' => "ali@bla.com"}
  # ...
]

但并非所有信息都在那里:

{'Name' => 'GuyWithNoTelephone', 'E-mail' => "poor@bla.com"}

我想将此信息转换为CSV文件。这是我试过的:

def to_csv (info)
  CSV.open("sm-data.csv", "wb") do |csv|
  csv << ["Name", "Tel", "E-mail"]
    info.each do |person|
      csv << person.values

当我尝试这个时,表的格式不正确,并且如果缺少电话号码,那么该人的电子邮件将出现在电话栏中。

如何选择性地将此信息写入CSV文件,即如果缺少值,如何跳过列?

3 个答案:

答案 0 :(得分:9)

  

但遗憾的是,当我尝试这个时,表的格式不正确,并说,如果缺少电话号码,那么该人的电子邮件会出现在电话栏中。

那是因为在这种情况下您省略了电话号码,只提供3个值中的2个。要解决此问题,您只需提供所有3个值,即使它们不存在于散列中:

csv << ['Name', 'Tel', 'E-mail']
info.each do |person|
  csv << [person['Name'], person['Tel'], person['E-Mail']]
end

或通过Hash#values_at

csv << ['Name', 'Tel', 'E-mail']
info.each do |person|
  csv << person.values_at('Name', 'Tel', 'E-Mail')
end

有关:

{'Name' => 'GuyWithNoTelephone', 'E-mail' => "poor@bla.com"}

这导致:

csv << ['GuyWithNoTelephone', nil, 'poor@bla.com']

生成此输出:(注意两个逗号,表示中间的空字段)

"GuyWithNoTelephone,,poor@bla.com\n"

答案 1 :(得分:4)

试试这个,

  def to_csv(csv_filename="sm-data.csv")
    # Get all unique keys into an array:
    keys = info.map(&:keys).inject(&:|)
    CSV.open(csv_filename, "wb") do |csv|
      csv << keys
      info.each do |hash|
        # fetch values at keys location, inserting null if not found.
        csv << hash.values_at(*keys)
      end
    end
  end

答案 2 :(得分:0)

很简单:

path = "data/backtest-results.csv"
CSV.open(path, "wb") do |csv|
  csv << ["Asset", "Strategy", "Profit"]
  result_array.each do |p|
    csv << p.map { |key, value| value }
  end
end

如果要随着新数据的到来继续添加,请使用“(File.file?(path)?” ab“:” wb“)”而不是“ wb”