2011-10-26 15 views
5

¿Hay alguna forma de imprimir rápidamente un hash de rubí en formato de tabla en un archivo? Tales como:¿Cómo imprimir rápidamente hashes de Ruby en un formato de tabla?

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

donde los valores de hash son matrices de diferentes tamaños. ¿O está utilizando un doble lazo de la única manera?

Gracias

+2

Lo más rápido es un "bucle doble", pero sigue siendo una sola línea; es tan malo? –

+0

IMO es demasiado especializado como para ser una característica integrada, y demasiado fácil de hacer "a mano" :) –

+0

No estaría mal que alguien publique el sencillo delineador. :-) – Larsenal

Respuesta

4

He aquí una versión de steenslag que funciona cuando las matrices no son del mismo tamaño:

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 parece como un marcador de posición razonable para los valores que faltan, pero se puede, por Por supuesto, usa lo que tenga sentido.

Por ejemplo:

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

Funciona siempre que las matrices tengan la misma longitud. – Larsenal

1

No, no hay ninguna función integrada. Aquí hay un código que define el formato que como quiera que:

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... 

Cualquier comentario y edita para refinar la respuesta son muy bienvenidos.

3

Prueba esta joya que escribí (hashes grabados, objetos de rubí, objetos ActiveRecord en las tablas): http://github.com/arches/table_print

+0

tp no funciona en un algoritmo hashing, funciona en un objeto AR. Cuando probé con un hash, obtengo this => table_print-1.0.1/lib/table_print/fingerprinter.rb: 38: en 'block in populate_row ' –

+0

En general, funciona en hashes. Si no funciona, abra un problema en http://github.com/arches/table_print o envíeme un correo electrónico sobre su problema ([email protected]) –

+0

error al desaparecer después de actualizar a la última versión, aún así no es el que estoy buscando, pero para la mesa, parece el mejor –

Cuestiones relacionadas