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
injecthier, 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_ecoenthä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