我要开始说我仍在学习红宝石。
我正在编写一个脚本以解析.csv并识别数据集中可能存在的重复记录。
我有一个带标头的.csv文件,因此我正在解析数据,以便可以使用标头标题访问每一行,例如:
@contact_table = CSV.parse(File.read("app/data/file.csv"), headers: true)
# Prints all last names in table
puts contact_table['last_name']
我正在尝试遍历表中的每一行,并确定我当前正在遍历的姓氏是否类似于下一个姓氏,但是这样做很麻烦。我想我的处理方式就像是数组一样,但是我检查了类型,它是CSV :: Row。
示例(这不起作用):
@contact_table.each_with_index do |c, i|
puts "first contact is #{c['last_name']}, second contact is #{c[i + 1]['last_name']}"
end
我意识到这不是这样,因为表不是数组,而是CSV :: Row,就像我之前提到的那样。有什么方法可以做到这一点?我现在真的很空白。
我的csv看起来像这样:
id,first_name,last_name,company,email,address1,address2,zip,city,state_long,state,phone
1,Donalt,Canter,Gottlieb Group,dcanter0@nydailynews.com,9 Homewood Alley,,50335,Des Moines,Iowa,IA,515-601-4495
2,Daphene,McArthur,"West, Schimmel and Rath",dmcarthur1@twitter.com,43 Grover Parkway,,30311,Atlanta,Georgia,GA,770-271-7837
答案 0 :(得分:2)
@contact_table
应该是CSV::Table
,它是CSV::Row
的集合,因此在此:
@contact_table.each_with_index do |c, i|
...
end
c
是CSV::Row
。这就是c['last_name']
起作用的原因。问题是在这里:
c[i + 1]['last_name']
您正在查看c
(单行)而不是@contact_table
,如果您说:
@contact_table[i + 1]['last_name']
那么您将得到下一个姓氏,或者当c
是最后一行时,会出现一个例外,因为@contact_table[i+1]
将是nil
。
此外,在迭代过程中,c
是当前(或第(i+1)
)行,并且不一定总是第一行。
答案 1 :(得分:1)
您的用例是什么?好像是学校的项目?
我建议使用for_each而不是解析(请参阅this comparison)。我可能为此使用Set。
rows
。rows.include?(row)
来解析文件
true
,则表示您有重复项rows.add(row)
将新行添加到集合中您还可以只使用必须与众不同的列(例如row.field(:some_column_name)
)中的单个值(例如电子邮件或电话号码)来填充集合,并对此进行相同的包含检查。
(如果这是用于真实应用程序,请不要这样做。请改用模型validations。)
答案 2 :(得分:0)
require 'csv'
LASTNAME_INDEX = 2
data = CSV.read('data.csv')
data[1..-1].each_with_index do |row, index|
puts "Contact number #{index + 1} has the following last name : #{row[LASTNAME_INDEX]}"
end
#~> Contact number 1 has the following last name : Canter
#~> Contact number 2 has the following last name : McArthur