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?
Die Antwort, die Sie haben, ist großartig, aber ich möchte Sie dringend bitten, CSV nicht zu verwenden. Wenn Ihre Daten keine Registerkarten enthalten, sind tabulatorgetrennte Dateien viel einfacher zu handhaben, da sie nicht so viel verdammtes Zitieren und Entkommen und dergleichen beinhalten. Wenn Sie CSV verwenden müssen, sind dies natürlich die Pausen.
Bill Dueber
8
@Bill, das CSV-Modul verarbeitet ordentlich durch Tabulatoren getrennte Dateien sowie tatsächliche CSV-Dateien. Mit der Option: col_sep können Sie das Spaltentrennzeichen als "\ t" angeben, und alles ist in Ordnung.
Die Verwendung von Tab-Dateien mit diesem Modul ist meine Aufgabe, da ein versehentliches Öffnen in Excel die Codierung anderweitig durcheinander bringen würde…
@ David ist es der Dateimodus. "w" bedeutet in eine Datei schreiben. Wenn Sie dies nicht angeben, wird standardmäßig "rb" (schreibgeschützter Binärmodus) verwendet, und beim Versuch, Ihrer CSV-Datei etwas hinzuzufügen, wird eine Fehlermeldung angezeigt. Eine Liste der gültigen Dateimodi in Ruby finden Sie unter ruby-doc.org/core-1.9.3/IO.html .
Dylan Markow
15
Erwischt. Wenn Sie für zukünftige Benutzer möchten, dass bei jeder Iteration die vorherige CSV-Datei nicht überschrieben wird, verwenden Sie die Option "ab".
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 +=1if rowid ==1
csv << hsh.keys# adding header row (column labels)else
csv << hsh.values
end# of if/else inside hshend# of hsh's (rows)end# of csv open
Wenn Ihre Daten nicht strukturiert sind, funktioniert dies offensichtlich nicht
Ich habe eine CSV-Datei mit CSV.table eingezogen, einige Manipulationen vorgenommen, einige Spalten entfernt, und jetzt möchte ich das resultierende Array von Hashes wieder als CSV (wirklich tabulatorgetrennt) herausspulen. Wie man? gist.github.com/4647196
Tamouse
hmm ... das Wesentliche ist etwas undurchsichtig, aber mit einer Reihe von Hashes, alle mit der gleichen Anzahl von k / v-Paaren und den gleichen Schlüsseln, in der gleichen Reihenfolge ...
boulder_ruby
Danke, @boulder_ruby. Das wird funktionieren. Die Daten sind eine Zensus-Tabelle, und dieser Kern ist im Rückblick ziemlich undurchsichtig. :) Grundsätzlich werden bestimmte Spalten aus der ursprünglichen Zensus-Tabelle in eine Teilmenge extrahiert.
Tamouse
3
Sie missbrauchen 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
iGEL
1
Ihr zweites Beispiel ist zu kompliziert, da die CSV-Bibliothek sehr leistungsfähig ist. CSV.generate(headers: hsh.first&.keys) { |csv| hsh.each { |e| csv << e } }generiert eine äquivalente CSV.
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.
Antworten:
Zu einer Datei:
Zu einer Zeichenfolge:
Hier ist die aktuelle Dokumentation zu CSV: http://ruby-doc.org/stdlib/libdoc/csv/rdoc/index.html
quelle
Ich habe das auf nur eine Zeile reduziert.
Führen Sie alle oben genannten Schritte aus und speichern Sie sie in einer Zeile in einem CSV.
HINWEIS:
Eine aktive Datensatzdatenbank in CSV zu konvertieren wäre ungefähr so, denke ich
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:
Wenn Ihre Daten nicht strukturiert sind, funktioniert dies offensichtlich nicht
quelle
inject
hier, Sie wollen wirklich verwendenmap
. Außerdem müssen Sie keine leere Zeichenfolge übergebenjoin
, 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:
Dann können Sie dies in eine Datei mit den folgenden Angaben schreiben, was meiner Meinung nach viel einfacher ist:
quelle
Wenn jemand interessiert ist, hier einige Einzeiler (und ein Hinweis zum Verlust von Typinformationen in CSV):
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.
quelle
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.Das Wesentliche wurde unter https://gist.github.com/tamouse/4647196 aktualisiert
quelle
Ich habe selbst damit zu kämpfen. Das ist meine Meinung:
https://gist.github.com/2639448 :
quelle
[ %w(your array), %w(goes here) ]
wird nicht schön aussehen. github.com/pry/pry/issues/568