检查CSV标头是否存在

问题描述 投票:3回答:3

我有我的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的情况下断开循环并保留代码DRY头。

编辑:

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

解决问题的方法

ruby csv
3个回答
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
投票

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

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的文档。

© www.soinside.com 2019 - 2024. All rights reserved.