【问题标题】:Why does my CSV write a header after each row?为什么我的 CSV 在每一行之后写一个标题?
【发布时间】:2016-10-07 04:57:52
【问题描述】:

我有一个名为 info 的数组,我想将每一行添加到 CSV,但我还想在文件顶部包含标题。

我这样做了:

  info.each do |listing|
    CSV.open(csvfile, "a+", write_headers: true, headers: ["Company_Name","Website","Street_Address", "City", "State", "Zip", "Phone","Email"]) do |csv|
      csv << listing
    end
  end

但这会产生如下所示的内容:

这不是我想要的。

我只想要顶部的 1 个标题行。

我如何做到这一点?

编辑 1

我实际上有另一个嵌套循环也有同样的问题,但我不能简单地将它移出循环 - 那我还能如何解决这个问题?

  csvs.each do |csv|
    CSV.foreach(csv, headers: true) do |row|
      #check for presence of valid email
      if (!row['Email'].nil?) && (!row['Email'].include? "no email")
        CSV.open(new_csv, "a+", write_headers: true, headers: ["Company_Name","Website","Street_Address", "City", "State", "Zip", "Phone","Email"]) do |new_csv_row|
          new_csv_row << row
          puts "#{row['Email']} successfully added to #{new_csv}"
        end
      end
    end
  end

【问题讨论】:

  • CSV.open 移出info.each 循环。
  • 当然!呸!愚蠢的我。完美,这就像一个魅力。您能否将其添加为答案,我会接受。谢谢!
  • @slowjack2k 实际上我还有 1 个用例发生这种情况。我已经更新了这个问题,所以您能否在添加答案之前查看它并提出解决方案以确保它是完整的。谢谢!

标签: ruby csv


【解决方案1】:

对于第一个更改循环:

CSV.open(csvfile, "a+", write_headers: true, headers: ["Company_Name","Website","Street_Address", "City", "State", "Zip", "Phone","Email"]) do |csv|
  info.each do |listing|
    csv << listing
  end
end

第二个:

header_written = {} # memorize if header is allready written
csvs.each do |csv|
  ...
  # alternative can be 'write_headers: !File.exist?(new_csv)'
  # but this works only when this file is created here and no empty file exists
  CSV.open(new_csv, "a+", write_headers: !header_written[new_csv], headers: ["Company_Name","Website","Street_Address", "City", "State", "Zip", "Phone","Email"]) do |new_csv_row|
          new_csv_row << row
          puts "#{row['Email']} successfully added to #{new_csv}"
  end
  header_written[new_csv] ||= true

编辑:我刚才确实认识到new_csv 不是动态的。因此,您可以将第二个 CSV.open 调用也放在循环之外,或者使用简单的标志而不是 header_written[],这样您就可以将其更改为 header_written = false|true

【讨论】:

  • 你也可以做each_with_index和特殊情况索引0。
  • 我认为索引 0 不起作用,因为 ifstatement。不是在第一个索引处创建 csv 文件。
  • 我的意思是你只需要在索引 0 上输出标题,其余的你可以忽略。如:write_headers: index == 0
  • 是的,我知道你的意思。但是请看一下if 声明(#check 是否存在有效电子邮件)。在第一次打开新的 csv 文件之前,您可以传递许多 csv 行。可能根本没有写入文件。
  • 没错,但这只是一种糟糕的形式。一个懒惰的枚举器和select 可以把这一切都整理好。
猜你喜欢
  • 2020-07-23
  • 2019-03-02
  • 2013-06-28
  • 2020-10-06
  • 1970-01-01
  • 1970-01-01
  • 2020-10-19
  • 2019-10-01
  • 1970-01-01
相关资源
最近更新 更多