How to split the content of one column into two columns of csv in Ruby?

非 Y 不嫁゛ 提交于 2020-05-09 17:22:47

问题


I got an object of CSV, the content is like:

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

And I would like to split the column of 'full_name' into two columns, which represents 'first_name' and 'last_name':

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

I didn't find a command to do it, how can I split it? Thank you very much!

The code for this part is:

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

And this method is called by:

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

The class type of 'books' is ActiveRecord_AssociationRelation, and I don't know how to split that full_name column into two columns, it looks like the String.split is not helpful.


回答1:


So far the question doesn't make enough sense so I expect it'll be closed eventually. Here's some information about how to split the fields so that, maybe, we can get to the real root of the problem.

Meditate on this:

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"]]

At this point it's possible to generate some usable CSV data:

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

Which results in:

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

Note the use of a regular expression as a parameter to split; This tells split to clean up the resulting output a bit by only splitting on zero-or-more whitespace delimited by |:

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"]

At that point it is easy to split the names:

first_name, last_name = full_name.split # => ["Mike", "Smith"],                        ["Tony", "Davis"]


来源:https://stackoverflow.com/questions/60858311/how-to-split-the-content-of-one-column-into-two-columns-of-csv-in-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!