Как разделить содержимое одного столбца на два столбца CSV в Ruby? - PullRequest
0 голосов
/ 26 марта 2020

Я получил объект CSV, содержимое выглядит так:

full_name  | phone_number  |
Mike Smith | (123)-456-7890|
Tony Davis | (213)-564-7890|

И я хотел бы разбить столбец 'full_name' на два столбца, которые представляют 'first_name' и 'last_name':

first_name | last_name | phone_number  |
Mike       | Smith     | (123)-456-7890|
Tony       | Davis     | (213)-564-7890|

Я не нашел команду, чтобы сделать это, как я могу разделить ее? Большое спасибо!

Код для этой части:

def to_csv(options = {})
  CSV.generate(options) do |csv|
    columns = %w[ full_name phone_number ]

    csv << columns
    each do |books|
      csv << columns.map { |column| books.public_send(column) }
                    .map { |column| ActionController::Base.helpers.strip_tags(column.to_s) }
    end
  end
end

И этот метод вызывается:

send_data(books.to_csv(col_sep: ','),filename: 'booksAuthorsInfo.csv',type: 'application/csv')

Тип класса 'books' ActiveRecord_AssociationRelation, и я не знаю, как разбить этот столбец с полным именем на два столбца, похоже, что String.split бесполезен.

1 Ответ

0 голосов
/ 26 марта 2020

Пока вопрос не имеет достаточного смысла, поэтому я ожидаю, что он будет закрыт в конце концов. Вот некоторая информация о том, как разделить поля так, чтобы возможно , мы могли получить реальную root проблемы.

Размышлять об этом:

ary = <<EOT
full_name  | phone_number  |
Mike Smith | (123)-456-7890|
Tony Davis | (213)-564-7890|
EOT

PIPE_DELIMITER = /\s*\|\s*/

munged_data = ary.lines[1..-1].map { |l|
  full_name, phone_number = l.split(PIPE_DELIMITER)  # => ["Mike Smith", "(123)-456-7890"], ["Tony Davis", "(213)-564-7890"]
  first_name, last_name = full_name.split # => ["Mike", "Smith"],                ["Tony", "Davis"]
  [first_name, last_name, phone_number]
}
# => [["Mike", "Smith", "(123)-456-7890"], ["Tony", "Davis", "(213)-564-7890"]]

На этом этапе можно сгенерировать некоторые используемые данные CSV:

require 'csv'
CSV.open("/dev/stdout", "wb") do |csv|
  csv << %w[first_name last_name phone_number]
  munged_data.each do |row|
    csv << row
  end
end

, что приводит к:

# >> first_name,last_name,phone_number
# >> Mike,Smith,(123)-456-7890
# >> Tony,Davis,(213)-564-7890

Обратите внимание на использование регулярного выражения в качестве параметра для split ; Это говорит split немного очистить результирующий вывод, разбивая его только на ноль или более пробелов, ограниченных |:

PIPE_DELIMITER = /\s*\|\s*/

full_name, phone_number = l.split('|')             # => ["Mike Smith ", " (123)-456-7890", "\n"], ["Tony Davis ", " (213)-564-7890", "\n"]
full_name, phone_number = l.split(PIPE_DELIMITER)  # => ["Mike Smith", "(123)-456-7890"],         ["Tony Davis", "(213)-564-7890"]

В этот момент легко разделить имена:

first_name, last_name = full_name.split # => ["Mike", "Smith"],                        ["Tony", "Davis"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...