Итерация по CSV :: Rows - PullRequest
       17

Итерация по CSV :: Rows

0 голосов
/ 26 сентября 2019

Я собираюсь предвосхитить, что я все еще изучаю ruby.

Я пишу скрипт для анализа .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

Ответы [ 3 ]

2 голосов
/ 26 сентября 2019

@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) th) строка и не всегда будет первой.

1 голос
/ 26 сентября 2019

Какой у вас вариант использования для этого?Похоже, школьный проект?

Я рекомендую for_each вместо анализа (см. это сравнение ).Я бы, вероятно, использовал для этого Set .

  • Создание набора вне области синтаксического анализа файла (т. Е. Выше кода синтаксического анализа).Давайте назовем это rows.
  • Вызывать rows.include?(row) во время каждой итерации при анализе файла
    • Если true, то вы знаете, что у вас есть дубликат
    • Если false, затем вызовите rows.add(row), чтобы добавить новую строку в набор

Вы также можете просто заполнить свой набор отдельным значением из столбца, который должен отличаться (например,row.field(:some_column_name)), например, адрес электронной почты или номер телефона, и сделайте для этого ту же проверку включения.

(Если это для реального приложения, не делайте этого. Используйте модель проверки вместо.)

0 голосов
/ 26 сентября 2019

Я бы использовал #read вместо #parse и сделал бы что-то вроде этого:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...