我的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
问题的解决方案
答案 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