2011-10-26 10 views
5

C'è un modo per stampare rapidamente un hash rubino in un formato tabella in un file? Come:Come stampare rapidamente gli hash Ruby in un formato tabella?

keyA keyB keyC ... 
123 234 345 
125   347 
4456 
... 

dove i valori di hash sono array di dimensioni diverse. O sta usando un doppio ciclo nell'unico modo?

Grazie

+2

più semplice è un "doppio ciclo", ma è ancora una battuta; è così brutto? –

+0

IMO è troppo specializzato per essere una funzione integrata e troppo facile da fare "a mano" :) –

+0

Non sarebbe male per qualcuno pubblicare la semplice copertina. :-) – Larsenal

risposta

4

Ecco una versione di steenslag di che funziona quando gli array non sono la stessa dimensione:

size = h.values.max_by { |a| a.length }.length 
m = h.values.map { |a| a += [nil] * (size - a.length) }.transpose.insert(0, h.keys) 

nil sembra un segnaposto ragionevole per i valori mancanti, ma è possibile, di Certo, usa qualsiasi cosa abbia un senso.

Ad esempio:

>> h = {:a => [1, 2, 3], :b => [4, 5, 6, 7, 8], :c => [9]} 
>> size = h.values.max_by { |a| a.length }.length 
>> m = h.values.map { |a| a += [nil] * (size - a.length) }.transpose.insert(0, h.keys) 
=> [[:a, :b, :c], [1, 4, 9], [2, 5, nil], [3, 6, nil], [nil, 7, nil], [nil, 8, nil]] 
>> m.each { |r| puts r.map { |x| x.nil?? '' : x }.inspect } 
[:a, :b, :c] 
[ 1, 4, 9] 
[ 2, 5, ""] 
[ 3, 6, ""] 
["", 7, ""] 
["", 8, ""] 
2
h = {:a => [1, 2, 3], :b => [4, 5, 6], :c => [7, 8, 9]} 
p h.values.transpose.insert(0, h.keys) 
# [[:a, :b, :c], [1, 4, 7], [2, 5, 8], [3, 6, 9]] 
+1

Funziona finchè gli array hanno la stessa lunghezza. – Larsenal

1

No, non c'è alcuna funzione built-in. Ecco un codice che avrebbe formattarlo come si desidera:

data = { :keyA => [123, 125, 4456], :keyB => [234000], :keyC => [345, 347] } 

length = data.values.max_by{ |v| v.length }.length 

widths = {} 
data.keys.each do |key| 
    widths[key] = 5 # minimum column width 

    # longest string len of values 
    val_len = data[key].max_by{ |v| v.to_s.length }.to_s.length 
    widths[key] = (val_len > widths[key]) ? val_len : widths[key] 

    # length of key 
    widths[key] = (key.to_s.length > widths[key]) ? key.to_s.length : widths[key] 
end 

result = "" 
data.keys.each {|key| result += key.to_s.ljust(widths[key]) + " " } 
result += "\n" 

for i in 0.upto(length) 
    data.keys.each { |key| result += data[key][i].to_s.ljust(widths[key]) + " " } 
    result += "\n" 
end 

# TODO write result to file... 

Eventuali osservazioni e modifiche per affinare la risposta sono i benvenuti.

3

Provate questo gioiello che ho scritto (stampe hash, oggetti rubino, oggetti ActiveRecord nelle tabelle): http://github.com/arches/table_print

+0

tp non funziona su un hash give, funziona su un oggetto AR. Quando ho provato su un hash, ottengo questo => table_print-1.0.1/lib/table_print/fingerprinter.rb: 38: in 'block in populate_row ' –

+0

In generale funziona sugli hash. Se non funziona, apri un problema su http://github.com/arches/table_print o inviami un'e-mail sul problema ([email protected]) –

+0

l'errore è scomparso dopo l'aggiornamento all'ultima versione, tuttavia non quello che sto cercando, ma per la cosa da tavolo, sembra il migliore –