2011-01-27 41 views
134

使用Ruby很容易將CSV文件讀入數組,但我找不到有關如何將數組寫入CSV文件的任何好文檔。誰能告訴我如何做到這一點?在Ruby中將數組輸出爲CSV

如果有問題,我使用的是Ruby 1.9.2。

+3

你有答案是偉大的,但讓我敦促你不要使用CSV。如果您的數據中沒有製表符,製表符分隔的文件更容易處理,因爲它們不涉及太多的引用和轉義等引用。如果你必須使用CSV,當然,他們是休息時間。 – 2011-01-28 01:45:40

+7

@Bill,CSV模塊整齊地處理製表符分隔的文件以及實際的csv文件。 :col_sep選項可讓您將列分隔符指定爲「\ t」,一切正常。 – tamouse 2013-11-13 17:42:11

+1

這裏是關於CSV的更多信息http://docs.ruby-lang.org/en/2.1.0/CSV.html – 2016-08-19 05:21:22

回答

246

到文件:

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當前文檔:http://ruby-doc.org/stdlib/libdoc/csv/rdoc/index.html

+0

什麼是「w」? – 2012-07-16 00:47:08

2

這種掙扎自己。這是我的看法:

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) ] 
27

我有了這個下降到只有一行。

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會是這樣,我認爲

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

嗯@tamouse,該要點是有點混亂我不讀取csv來源,但一般來說,假設陣列中的每個散列具有相同數量的k/v對&這些鍵總是相同的,以相同的順序(即if你的數據是結構化的),這應該做的契稅:

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 

如果沒有結構化的數據,這顯然不會對@ boulder_ruby的回答工作

7

大廈,這就是我要找的,假設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

13

如果有人有興趣,這裏有一些單行(以及在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中的字符串& JSON。

10

如果你有數據數組的數組:

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

然後,你可以寫這與以下,我認爲一個文件要簡單得多:

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