Es ist einfach genug, eine CSV-Datei mit Ruby in ein Array einzulesen, aber ich kann keine gute Dokumentation zum Schreiben eines Arrays in eine CSV-Datei finden. Kann mir jemand sagen, wie das geht?
Ich verwende Ruby 1.9.2, wenn das wichtig ist.
Es ist einfach genug, eine CSV-Datei mit Ruby in ein Array einzulesen, aber ich kann keine gute Dokumentation zum Schreiben eines Arrays in eine CSV-Datei finden. Kann mir jemand sagen, wie das geht?
Ich verwende Ruby 1.9.2, wenn das wichtig ist.
Antworten:
Zu einer Datei:
require 'csv'
CSV.open("myfile.csv", "w") do |csv|
csv << ["row", "of", "CSV", "data"]
csv << ["another", "row"]
# ...
end
Zu einer Zeichenfolge:
require 'csv'
csv_string = CSV.generate do |csv|
csv << ["row", "of", "CSV", "data"]
csv << ["another", "row"]
# ...
end
Hier ist die aktuelle Dokumentation zu CSV: http://ruby-doc.org/stdlib/libdoc/csv/rdoc/index.html
Ich habe das auf nur eine Zeile reduziert.
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"
Führen Sie alle oben genannten Schritte aus und speichern Sie sie in einer Zeile in einem CSV.
File.open("ss.csv", "w") {|f| f.write(rows.inject([]) { |csv, row| csv << CSV.generate_line(row) }.join(""))}
HINWEIS:
Eine aktive Datensatzdatenbank in CSV zu konvertieren wäre ungefähr so, denke ich
CSV.open(fn, 'w') do |csv|
csv << Model.column_names
Model.where(query).each do |m|
csv << m.attributes.values
end
end
Hmm @tamouse, das Wesentliche ist für mich etwas verwirrend, ohne die CSV-Quelle zu lesen, aber im Allgemeinen, vorausgesetzt, jeder Hash in Ihrem Array hat die gleiche Anzahl von k / v-Paaren und die Schlüssel sind immer gleich, in der gleichen Reihenfolge (dh Wenn Ihre Daten strukturiert sind, sollte dies die Tat tun:
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
Wenn Ihre Daten nicht strukturiert sind, funktioniert dies offensichtlich nicht
inject
hier, Sie wollen wirklich verwenden map
. Außerdem müssen Sie keine leere Zeichenfolge übergeben join
, da dies die Standardeinstellung ist. Sie könnten es also noch weiter verkleinern:rows.map(&CSV.method(:generate_line).join
CSV.generate(headers: hsh.first&.keys) { |csv| hsh.each { |e| csv << e } }
generiert eine äquivalente CSV.
Wenn Sie ein Array von Datenfeldern haben:
rows = [["a1", "a2", "a3"],["b1", "b2", "b3", "b4"], ["c1", "c2", "c3"]]
Dann können Sie dies in eine Datei mit den folgenden Angaben schreiben, was meiner Meinung nach viel einfacher ist:
require "csv"
File.write("ss.csv", rows.map(&:to_csv).join)
Wenn jemand interessiert ist, hier einige Einzeiler (und ein Hinweis zum Verlust von Typinformationen 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
Hinweis: CSV verliert alle Typinformationen. Sie können JSON verwenden, um grundlegende Typinformationen beizubehalten, oder YAML verwenden, um alle Typinformationen beizubehalten, z. B. wenn Sie einen Datumstyp benötigen Zeichenfolgen in CSV & JSON.
Aufbauend auf der Antwort von @ boulder_ruby ist dies das, wonach ich suche, vorausgesetzt, es us_eco
enthält die CSV-Tabelle aus meiner Sicht.
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
Das Wesentliche wurde unter https://gist.github.com/tamouse/4647196 aktualisiert
Ich habe selbst damit zu kämpfen. Das ist meine Meinung:
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) ]
[ %w(your array), %w(goes here) ]
wird nicht schön aussehen. github.com/pry/pry/issues/568