首页 > 解决方案 > 如何在 Ruby 中将数组添加到 CSV 文件的列中?

问题描述

我正在使用 ruby​​ 构建一个 CSV 文件,并且我有不同的列,即

“公司名称”、“公司电话”

公司名称没有问题,因为它是一个简单的字符串,但公司有不止一部电话,在我的代码中存储为

电话= [电话1,电话2]

当我将其添加到 CSV 中时,如下所示:

      CSV.open("output.csv", "a") do |csv|
    csv << [
      company_name,
      company_phones,
    ]
  end

我尝试了不同的方法来做到这一点,但它最终:

1) 用双双引号显示 ([""Phone1"", ""Phone2""]) 2) 这在读取 CSV 时显示为 ["\"Phone1"", "\"Phone2""]它甚至不是一个数组,而是一个字符串。

有什么我遗漏的东西,或者只是无法编写 CSV,我应该改变我的输出格式?

标签: arraysruby-on-railsrubycsv

解决方案


这种情况需要 CSV自定义转换器

写入 CSV 文件

让我们首先根据以下信息创建一个 CSV 文件。

FName = 't.csv'

headers = ["company", "vals", "phone_nbrs"]
rows = [
  ['ABC', [1.3, 2.1, 4.1], ["800-555-1000", "800-555-1001"]],
  ['XYZ', [7.3, 9.5], ["800-555-2000", "800-555-2001"]] 
]

我将通过将每个rows数组转换为包含转换为字符串并用空格分隔的数组元素的字符串来做到这一点。例如,[1.3, 2.1, 4.1]将保存为字符串:

[1.3, 2.1, 4.1].join(' ')
  #=> "1.3 2.1 4.1"

正如将要看到的,这种特定的数组字符串表示是任意的,只是众多方法中的一种。例如,我们可以将上面显示的浮点数组保存为"1.3:2.1:4.1""1.3¯\\_(ツ)_/¯2.1¯\\_(ツ)_/¯4.1"

现在让我们创建 CSV 文件。

require 'csv'

CSV.open(FName, "w") do |csv|
  csv << headers
  rows.each { |name,vals,phone_nbrs|
    csv << [name, vals.join(' '), phone_nbrs.join(' ')] }
end

让我们看看写了什么。

puts File.read(FName)
company,vals,phone_nbrs
ABC,1.3 2.1 4.1,800-555-1000 800-555-1001
XYZ,7.3 9.5,800-555-2000 800-555-2001

读取 CSV 文件

这里的技巧是定义一个转换器,它将表示浮点数的字符串转换为浮点数组,并将电话号码字符串转换为字符串数组。

convert_arrays = lambda do |value, field|
  case field.header
  when 'vals'
    value.split.map(&:to_f)
  when 'phone_nbrs'
    value.split
  else
    value
  end
end
  #=> #<Proc:0x0000599427913ec0@(irb):19 (lambda)> 

现在将文件读入一个数组。

CSV.foreach(FName, :headers => true, converters: [convert_arrays]).
  with_object([]) { |row, arr|
    arr << row.values_at('company', 'vals', 'phone_nbrs') }
  #=> [["ABC", [1.3, 2.1, 4.1], ["800-555-1000", "800-555-1001"]],
  #    ["XYZ", [7.3, 9.5], ["800-555-2000", "800-555-2001"]]]

请参阅CSV::new这些 CSV 转换器示例


推荐阅读