web-dev-qa-db-de.com

So speichern Sie einen Hash in einem CSV

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? 

34
TheLegend

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
40
Sławosz

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)

52
Joe Goggins

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
23
Tom Rossi

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.

6
rudolph9

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
4
peter

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
1
Santosh Sharma

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. 

0
shubham mishra