【问题标题】:How to add new column in CSV string in rails如何在rails中的CSV字符串中添加新列
【发布时间】:2019-03-03 04:34:29
【问题描述】:

我想在 CSV 响应中添加新列并更新现有值。我怎样才能更简单更好地进行以下转换?

输入

id,name,country
1,John,US
2,Jack,UK
3,Sam,UK

我正在使用以下方法来解析 csv 字符串并添加新列

# Parse original CSV
rows = CSV.parse(csv_string, headers: true).collect do |row|
  hash = row.to_hash
  # Merge additional data as a hash.
  hash.merge('email' => 'sample@gmail.com')
end

# Extract column names from first row of data
column_names = rows.first.keys
# Generate CSV after transformation of csv
csv_response = CSV.generate do |csv|
  csv << column_names
  rows.each do |row|
    # Extract values for row of data
    csv << row.values_at(*column_names)
  end
end

我正在使用以下方法来解析 csv 并更新现有值

name_hash = {"John" => "Johnny", "Jack" => "Jackie"}

解析原始 CSV

rows = CSV.parse(csv_string, headers: true).collect do |row|
  hash = row.to_hash
  hash['name'] = name_hash[hash['name']] if name_hash[hash['name']] != nil
  hash
end

# Extract column names from first row of data
column_names = rows.first.keys
# Generate CSV after transformation of csv
csv_response = CSV.generate do |csv|
  csv << column_names
  rows.each do |row|
    # Extract values for row of data
    csv << row.values_at(*column_names)
  end
end

【问题讨论】:

    标签: ruby-on-rails csv parsing


    【解决方案1】:

    给定以下用于修改表的参考数据的一个可能选项:

    name_hash = {"John" => "Johnny", "Jack" => "Jackie"}
    sample_email = {'email' => 'sample@gmail.com'}
    

    只需将转换为哈希的表存储在行中:

    rows = CSV.parse(csv_string, headers: true).map(&:to_h)
    #=> [{"id"=>"1", "name"=>"John", "country"=>"US"}, {"id"=>"2", "name"=>"Jack", "country"=>"UK"}, {"id"=>"3", "name"=>"Sam", "country"=>"UK"}]
    


    然后根据参考数据修改哈希(我使用Object#then 表示Ruby 2.6.1 别名Object#yield_self 表示Ruby 2.5):
    rows.each { |h| h.merge!(sample_email).then {|h| h['name'] = name_hash[h['name']] if name_hash[h['name']] } }
    #=> [{"id"=>"1", "name"=>"Johnny", "country"=>"US", "email"=>"sample@gmail.com"}, {"id"=>"2", "name"=>"Jackie", "country"=>"UK", "email"=>"sample@gmail.com"}, {"id"=>"3", "name"=>"Sam", "country"=>"UK", "email"=>"sample@gmail.com"}]
    


    最后恢复表:
    csv_response = CSV.generate(headers: rows.first.keys) { |csv| rows.map(&:values).each { |v| csv << v } }
    

    所以你现在有:

    puts csv_response
    
    # id,name,country,email
    # 1,Johnny,US,sample@gmail.com
    # 2,Jackie,UK,sample@gmail.com
    # 3,Sam,UK,sample@gmail.com
    

    【讨论】:

    • 您的解决方案是否会提供比上述方法更好的性能?我想用更简单的代码更好地处理 csv。
    猜你喜欢
    • 2020-11-14
    • 1970-01-01
    • 2022-01-13
    • 2020-03-08
    • 2020-06-29
    • 1970-01-01
    • 2017-10-01
    • 2016-05-02
    • 2020-02-23
    相关资源
    最近更新 更多