检查CSV标头是否存在

时间:2015-04-28 08:26:52

标签: ruby csv

我的Rails应用程序的类导入器,我在其中使用方法导入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来执行循环内的操作,我尝试保护它不受邮件列的不同名称的影响,但我不知道应该如何打破循环并保留代码DRY以防万一没有任何已定义标题的列的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

问题的解决方案

3 个答案:

答案 0 :(得分: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,因为您不想扫描每一行的标题,因为它们都是相同的。

答案 1 :(得分:0)

也可以尝试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上的文档。

答案 2 :(得分:0)

根据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