2016-05-28 3 views
-3

Ich habe einen Hash, der wie folgt aussieht:Rubin konvertieren Hash in csv Histogramm

@histogram = { 
    "Date 1" => [ 
    {"Item 1" => 1}, 
    {"Item 4" => 3} 
    ], 
    "Date 2" => [ 
    {"Item 2" => 7}, 
    {"Item 1" => 2}, 
    {"Item 5" => 1} 
    ], 
    "Date 3" => [ 
    {"Item 4" => 3}, 
    {"Item 2" => 2}, 
    {"Item 8" => 1}, 
    {"Item 1" => 5} 
    ] 
} 

Ich möchte, dass von Tag Histogramm CSV-Datei in einen Tag konvertieren, die wie folgt aussieht:

|  | Date 1 | Date 2 | Date 3 | 
| Item 1 | 1 | 2 | 5 | 
| Item 2 |  | 7 | 2 | 
| Item 4 | 3 |  | 3 | 
| Item 5 |  | 1 |  | 
| Item 8 |  |  | 8 | 

Was mich stolpert, ist die Tatsache, dass der Hash @histogram völlig außer Betrieb sein kann. Die Daten (keys) sind wahrscheinlich in Ordnung, aber die Artikel werden völlig außer Betrieb sein. Außerdem, wie Sie sehen können, müssen die Elemente nicht über verschiedene Daten hinweg identisch sein. Wenn ein Element an einem bestimmten Datum nicht vorhanden ist, kann die Menge im Histogramm als 0 angenommen werden.

+0

Scheint, wie Sie ein bisschen Umpacken des Inhalts dieser Hash in Strukturen temporären Daten zu tun haben, um Ihre CSV leichter zu konstruieren. Angenommen du nimmst diese Idee und liegst damit. Ich frage mich, welche Art von Code Sie produzieren könnten. – MarsAtomic

+0

Für Ihr erstes Problem - Sie können sort verwenden. Für die zweite - holen Sie sich die Vereinigung der Schlüssel vorher. – ndn

Antwort

0

Ich sehe nicht viel Sinn für Array von Hashes für Date1 Wert, es könnte sehr gut single Hash sein mit mehreren Schlüsseln. Die Struktur Ihrer @histogram sollte vorzugsweise wie unten sein:

{"Date 1"=>{"Item 1"=>1, "Item 4"=>3}, 
"Date 2"=>{"Item 2"=>7, "Item 1"=>2, "Item 5"=>1}, 
"Date 3"=>{"Item 4"=>3, "Item 2"=>2, "Item 8"=>1, "Item 1"=>5}} 

Daher werde ich Lösung geben, die @histogram oben Struktur und darauf aufbauen, dass konvertieren.

processed_hash = @histogram.map {|k,v| [k, v.reduce(&:merge)]}.to_h 

column_headers = processed_hash.keys 
row_headers = processed_hash.flat_map{ |k, v| v.keys}.uniq.sort 

print "|" + "".center(10) + "|" 
column_headers.each {|ch| print ch.center(10) + "|"} 
puts 
row_headers.each do |rh| 
    print "|" + rh.center(10) + "|" 
    column_headers.each {|ch| print processed_hash.dig(ch, rh).to_s.center(10) + "|"} 
    puts 
end 

Ausgang:

|   | Date 1 | Date 2 | Date 3 | 
| Item 1 | 1  | 2  | 5  | 
| Item 2 |   | 7  | 2  | 
| Item 4 | 3  |   | 3  | 
| Item 5 |   | 1  |   | 
| Item 8 |   |   | 1  |