【问题标题】:Check if CSV header exists检查 CSV 标头是否存在
【发布时间】:2015-04-28 08:26:52
【问题描述】:

我的 Rails 应用程序有类 Importer,我在其中使用方法导入 CSV 文件。

def import
  CSV.foreach(file.path, headers: true, encoding: "iso-8859-1") do |row|
    mail = row["email"]||row["Email"]||row["e-mail"]||row["E-mail"]||row["mail"]||row["Mail"]
  end
end

我设置变量mail 在循环内执行操作,我尝试保护它免受邮件列的不同名称的影响,但我不知道应该如何打破循环并保持代码干燥,以防CSV 没有具有任何已定义标题的列。

编辑:

def import
  header = nil
  headers = CSV.open(file.path, encoding: "iso-8859-1") { |csv| csv.first }
  headers.each { |e| header = e if e.downcase.gsub('-','')=~/^(|e)mail$/ }
  if header != nil
    CSV.foreach(file.path, headers: true, encoding: "iso-8859-1") do |row|
      mail = row[header]
    end
  end
end

解决问题

【问题讨论】:

  • fail 'No email in input data' unless mail
  • 可以,但是单条记录没有email的时候会失败。
  • 你声称你希望它“应该打破一个循环”。要简单地跳过记录,请使用next if mail.nil?
  • 也许我描述错了。如果没有名为“email”、“Email”等的列,我想打破循环或者甚至不启动它。如果它会在定义的列中找到记录,我的邮件变量只是单个电子邮件,但如果没有列将始终为零。

标签: ruby csv


【解决方案1】:

这应该可以帮助您入门。您需要更改正则表达式以匹配您的所有情况。

def import
  CSV.foreach(file.path, headers: true, encoding: "iso-8859-1") do |row|
    if row.headers.none?{|e| e =~ /email/i}
      raise "freak out"
    end
  end
end

我还会考虑设置一个变量has_email_headers,您可以检查它,因为您不想扫描每一行的标题,因为它们都是相同的。

【讨论】:

  • 谢谢,这就是我要找的。我观察到,如果你把它放在循环中,它会大大减慢导入速度。我已经使用了您的想法并创建了自己的想法来跳过循环内的实现。我会更新我的帖子。
【解决方案2】:

根据CSV documentation of Ruby 2.5.0,您也可以稍后在循环中使用return_headers:true 来检查header_row?。这是一个例子:

data = CSV.read("your.csv", headers: true, return_headers: true)
(0..(data.length-1)).each do |row|
   if  data[row].header_row? then
      p "yes header!"
   end
end

【讨论】:

    【解决方案3】:

    Once 也可以尝试header_converters: [:downcase, :symbol] 选项,只需要检查更少的值(即不区分大小写),例如[:email, :mail]

    CSV.foreach(file.path, headers: true, header_converters: [:downcase, :symbol], encoding: "iso-8859-1") do |row|
      puts 'You are missing the "email" header!' unless [:email, :mail].all? { |header| row.headers.include? header }
      # refine/refactor as necessary...
      # do rest of function...
    end
    

    :header_converters 上的文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-21
      • 2011-02-09
      • 2022-08-23
      • 1970-01-01
      • 1970-01-01
      • 2014-06-17
      • 1970-01-01
      • 2021-11-15
      相关资源
      最近更新 更多