Ich bin neu in Ruby, bitte verzeihen Sie das Noobishness.
Ich habe eine CSV mit zwei Spalten. Einer für den Namen des Tieres und einer für den Tiertyp . Ich habe einen Hash, wobei alle Schlüssel Tiernamen sind und die Werte Tiertyp sind. Ich möchte den Hash in das CSV schreiben, ohne das Dienstprogramm "schnelleres CSV" zu verwenden. Ich habe an einige Ideen gedacht, was am einfachsten wäre. Hier ist das grundlegende Layout.
require "csv"
def write_file
h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
CSV.open("data.csv", "wb") do |csv|
csv << [???????????]
end
end
Als ich die Datei zum Lesen geöffnet habe, habe ich sie File.open("blabla.csv", headers: true)
.__ geöffnet. Wäre es möglich, die Datei auf dieselbe Weise zurückzuschreiben?
Versuche dies:
require 'csv'
h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
CSV.open("data.csv", "wb") {|csv| h.to_a.each {|elem| csv << elem} }
Wird resultieren:
1.9.2-p290:~$ cat data.csv
dog,canine
cat,feline
donkey,asinine
Wenn Sie Spaltenüberschriften wünschen und mehrere Hashes haben:
require 'csv'
hashes = [{'a' => 'aaaa', 'b' => 'bbbb'}]
column_names = hashes.first.keys
s=CSV.generate do |csv|
csv << column_names
hashes.each do |x|
csv << x.values
end
end
File.write('the_file.csv', s)
(getestet mit Ruby 1.9.3-p429)
Ich denke, die einfachste Lösung für Ihre ursprüngliche Frage:
def write_file
h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
CSV.open("data.csv", "w", headers: h.keys) do |csv|
csv << h.values
end
end
Mit mehreren Hashes die alle dieselben Schlüssel teilen :
def write_file
hashes = [ { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' },
{ 'dog' => 'rover', 'cat' => 'kitty', 'donkey' => 'ass' } ]
CSV.open("data.csv", "w", headers: hashes.first.keys) do |csv|
hashes.each do |h|
csv << h.values
end
end
end
CSV kann einen Hashwert in beliebiger Reihenfolge annehmen, Elemente ausschließen und keine Parameter in der Variablen HEADERS
auslassen.
require "csv"
HEADERS = [
'dog',
'cat',
'donkey'
]
def write_file
CSV.open("data.csv", "wb", :headers => HEADERS, :write_headers => true) do |csv|
csv << { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
csv << { 'dog' => 'canine'}
csv << { 'cat' => 'feline', 'dog' => 'canine', 'donkey' => 'asinine' }
csv << { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine', 'header not provided in the options to #open' => 'not included in output' }
end
end
write_file # =>
# dog,cat,donkey
# canine,feline,asinine
# canine,,
# canine,feline,asinine
# canine,feline,asinine
Dadurch wird das Arbeiten mit der CSV-Klasse flexibler und lesbarer.
Ich habe die Lösungen hier versucht, aber ein falsches Ergebnis erhalten (Werte in falschen Spalten), da meine Quelle eine LDIF-Datei ist, die nicht immer alle Werte für einen Schlüssel enthält. Am Ende habe ich folgendes verwendet.
Erstens erinnere ich mich beim Aufbau des Hash an die Schlüssel in einem separaten Array, das ich mit den Schlüsseln aussteige, die nicht bereits dort sind.
# building up the array of hashes
File.read(ARGV[0]).each_line do |lijn|
case
when lijn[0..2] == "dn:" # new record
record = {}
when lijn.chomp == '' # end record
if record['telephonenumber'] # valid record ?
hashes << record
keys = keys.concat(record.keys).uniq
end
when ...
end
end
Die wichtige Zeile hier ist keys = keys.concat(record.keys).uniq
, die das Tastenfeld erweitert, wenn neue Schlüssel (Header) gefunden werden.
Nun das Wichtigste: Konvertieren unserer Hashes in ein CSV
CSV.open("export.csv", "w", {headers: keys, col_sep: ";"}) do |row|
row << keys # add the headers
hashes.each do |hash|
row << hash # the whole hash, not just the array of values
end
end
Versuche dies:
require 'csv'
data = { 'one' => '1', 'two' => '2', 'three' => '3' }
CSV.open("data.csv", "a+") do |csv|
csv << data.keys
csv << data.values
end
Lasst uns einen Hash haben,
hash_1 = {1=>{:rev=>400, :d_odr=>3}, 2=>{:rev=>4003, :d_price=>300}}
Der obige Hash_1 mit Schlüsseln als ID 1,2, .. und Werten für diese sind wiederum Hashwerte mit einigen Schlüsseln als (: rev,: d_odr,: d_price) . Angenommen, wir möchten eine CSV-Datei mit Kopfzeilen.
headers = ['Designer_id','Revenue','Discount_price','Impression','Designer ODR']
Erstellen Sie dann für jeden Wert von Hash_1 ein neues Array und fügen Sie es in die CSV-Datei ein.
CSV.open("design_performance_data_temp.csv", "w") do |csv|
csv << headers
csv_data = []
result.each do |design_data|
csv_data << design_data.first
csv_data << design_data.second[:rev] || 0
csv_data << design_data.second[:d_price] || 0
csv_data << design_data.second[:imp] || 0
csv_data << design_data.second[:d_odr] || 0
csv << csv_data
csv_data = []
end
end
Nun haben Sie die Datei design_performance_data_temp.csv in Ihrem entsprechenden Verzeichnis gespeichert.