在 Ruby 中将数组输出到 CSV

发布于 2024-10-14 23:09:18 字数 103 浏览 1 评论 0原文

使用 Ruby 将 CSV 文件读入数组很容易,但我找不到任何关于如何将数组写入 CSV 文件的好的文档。谁能告诉我该怎么做?

如果重要的话,我正在使用 Ruby 1.9.2。

It's easy enough to read a CSV file into an array with Ruby but I can't find any good documentation on how to write an array into a CSV file. Can anyone tell me how to do this?

I'm using Ruby 1.9.2 if that matters.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

云雾 2024-10-21 23:09:18

到文件:

require 'csv'
CSV.open("myfile.csv", "w") do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
  # ...
end

到字符串:

require 'csv'
csv_string = CSV.generate do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
  # ...
end

这是 CSV 的当前文档:(直到 3.1.1 才替换 1.9.2)

https://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/ CSV.html#class-CSV-label-Writing

而 3.1.2 至最新版本(截至本次编辑为 3.2.2)

https://ruby-doc.org/3.2.2/stdlibs/csv /CSV.html

To a file:

require 'csv'
CSV.open("myfile.csv", "w") do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
  # ...
end

To a string:

require 'csv'
csv_string = CSV.generate do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
  # ...
end

Here's the current documentation on CSV: (until 3.1.1 just replace 1.9.2)

https://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html#class-CSV-label-Writing

while 3.1.2 up to latest (3.2.2 as of this edit).

https://ruby-doc.org/3.2.2/stdlibs/csv/CSV.html

浅唱ヾ落雨殇 2024-10-21 23:09:18

如果您有一个数据数组的数组:

rows = [["a1", "a2", "a3"],["b1", "b2", "b3", "b4"], ["c1", "c2", "c3"]]

那么您可以使用以下内容将其写入文件,我认为这要简单得多:

require "csv"
File.write("ss.csv", rows.map(&:to_csv).join)

If you have an array of arrays of data:

rows = [["a1", "a2", "a3"],["b1", "b2", "b3", "b4"], ["c1", "c2", "c3"]]

Then you can write this to a file with the following, which I think is much simpler:

require "csv"
File.write("ss.csv", rows.map(&:to_csv).join)
筑梦 2024-10-21 23:09:18

我把它简化为一行。

rows = [['a1', 'a2', 'a3'],['b1', 'b2', 'b3', 'b4'], ['c1', 'c2', 'c3'], ... ]
csv_str = rows.inject([]) { |csv, row|  csv << CSV.generate_line(row) }.join("")
#=> "a1,a2,a3\nb1,b2,b3\nc1,c2,c3\n" 

在一行中执行所有上述操作保存到 csv。

File.open("ss.csv", "w") {|f| f.write(rows.inject([]) { |csv, row|  csv << CSV.generate_line(row) }.join(""))}

注意:

要将活动记录数据库转换为 csv,我认为嗯@tamouse,在不阅读 csv 源代码的情况下

CSV.open(fn, 'w') do |csv|
  csv << Model.column_names
  Model.where(query).each do |m|
    csv << m.attributes.values
  end
end

,这个要点对我来说有点令人困惑,但一般来说,假设数组中的每个散列具有相同数量的 k/ v 对 &键始终相同,顺序相同(即,如果您的数据是结构化的),这应该执行以下操作:

rowid = 0
CSV.open(fn, 'w') do |csv|
  hsh_ary.each do |hsh|
    rowid += 1
    if rowid == 1
      csv << hsh.keys# adding header row (column labels)
    else
      csv << hsh.values
    end# of if/else inside hsh
  end# of hsh's (rows)
end# of csv open

如果您的数据不是结构化的,这显然是行不通的

I've got this down to just one line.

rows = [['a1', 'a2', 'a3'],['b1', 'b2', 'b3', 'b4'], ['c1', 'c2', 'c3'], ... ]
csv_str = rows.inject([]) { |csv, row|  csv << CSV.generate_line(row) }.join("")
#=> "a1,a2,a3\nb1,b2,b3\nc1,c2,c3\n" 

Do all of the above and save to a csv, in one line.

File.open("ss.csv", "w") {|f| f.write(rows.inject([]) { |csv, row|  csv << CSV.generate_line(row) }.join(""))}

NOTE:

To convert an active record database to csv would be something like this I think

CSV.open(fn, 'w') do |csv|
  csv << Model.column_names
  Model.where(query).each do |m|
    csv << m.attributes.values
  end
end

Hmm @tamouse, that gist is somewhat confusing to me without reading the csv source, but generically, assuming each hash in your array has the same number of k/v pairs & that the keys are always the same, in the same order (i.e. if your data is structured), this should do the deed:

rowid = 0
CSV.open(fn, 'w') do |csv|
  hsh_ary.each do |hsh|
    rowid += 1
    if rowid == 1
      csv << hsh.keys# adding header row (column labels)
    else
      csv << hsh.values
    end# of if/else inside hsh
  end# of hsh's (rows)
end# of csv open

If your data isn't structured this obviously won't work

自由如风 2024-10-21 23:09:18

如果有人感兴趣,这里有一些俏皮话(以及关于 CSV 中类型信息丢失的注释):

require 'csv'

rows = [[1,2,3],[4,5]]                    # [[1, 2, 3], [4, 5]]

# To CSV string
csv = rows.map(&:to_csv).join             # "1,2,3\n4,5\n"

# ... and back, as String[][]
rows2 = csv.split("\n").map(&:parse_csv)  # [["1", "2", "3"], ["4", "5"]]

# File I/O:
filename = '/tmp/vsc.csv'

# Save to file -- answer to your question
IO.write(filename, rows.map(&:to_csv).join)

# Read from file
# rows3 = IO.read(filename).split("\n").map(&:parse_csv)
rows3 = CSV.read(filename)

rows3 == rows2   # true
rows3 == rows    # false

注意:CSV 会丢失所有类型信息,您可以使用 JSON 来保留基本类型信息,或者转到详细信息(但更容易)人类可编辑)YAML 来保留所有类型信息——例如,如果您需要日期类型,它将成为 CSV 和 CSV 中的字符串。 JSON。

If anyone is interested, here are some one-liners (and a note on loss of type information in CSV):

require 'csv'

rows = [[1,2,3],[4,5]]                    # [[1, 2, 3], [4, 5]]

# To CSV string
csv = rows.map(&:to_csv).join             # "1,2,3\n4,5\n"

# ... and back, as String[][]
rows2 = csv.split("\n").map(&:parse_csv)  # [["1", "2", "3"], ["4", "5"]]

# File I/O:
filename = '/tmp/vsc.csv'

# Save to file -- answer to your question
IO.write(filename, rows.map(&:to_csv).join)

# Read from file
# rows3 = IO.read(filename).split("\n").map(&:parse_csv)
rows3 = CSV.read(filename)

rows3 == rows2   # true
rows3 == rows    # false

Note: CSV loses all type information, you can use JSON to preserve basic type information, or go to verbose (but more easily human-editable) YAML to preserve all type information -- for example, if you need date type, which would become strings in CSV & JSON.

江心雾 2024-10-21 23:09:18

基于 @boulder_ruby 的答案,这就是我正在寻找的内容,假设 us_eco 包含我的要点中的 CSV 表。

CSV.open('outfile.txt','wb', col_sep: "\t") do |csvfile|
  csvfile << us_eco.first.keys
  us_eco.each do |row|
    csvfile << row.values
  end
end

更新了要点 https://gist.github.com/tamouse/4647196

Building on @boulder_ruby's answer, this is what I'm looking for, assuming us_eco contains the CSV table as from my gist.

CSV.open('outfile.txt','wb', col_sep: "\t") do |csvfile|
  csvfile << us_eco.first.keys
  us_eco.each do |row|
    csvfile << row.values
  end
end

Updated the gist at https://gist.github.com/tamouse/4647196

来日方长 2024-10-21 23:09:18

我自己也在为此苦苦挣扎。这是我的看法:

https://gist.github.com/2639448

require 'csv'

class CSV
  def CSV.unparse array
    CSV.generate do |csv|
      array.each { |i| csv << i }
    end
  end
end

CSV.unparse [ %w(your array), %w(goes here) ]

Struggling with this myself. This is my take:

https://gist.github.com/2639448:

require 'csv'

class CSV
  def CSV.unparse array
    CSV.generate do |csv|
      array.each { |i| csv << i }
    end
  end
end

CSV.unparse [ %w(your array), %w(goes here) ]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文