ruby - sprintf - tipos de pestañas postizas nombres
Muy bien formatear la salida a la consola, especificando el número de pestañas (7)
Escribí una cosa
- Detecta automáticamente anchos de columna
- Espacios con espacios
- Matriz de matrices
[[],[],...]
o matriz de hash[{},{},...]
No detecta columnas demasiado anchas para la ventana de la consola
lists = [[123, "SDLKFJSLDKFJSLDKFJLSDKJF"], [123456, "ffff"],]
array_maxes
def array_maxes(lists)
lists.reduce([]) do |maxes, list|
list.each_with_index do |value, index|
maxes[index] = [(maxes[index] || 0), value.to_s.length].max
end
maxes
end
end
array_maxes(lists)
# => [6, 24]
puts_arrays_columns
def puts_arrays_columns(lists)
maxes = array_maxes(hashes)
lists.each do |list|
list.each_with_index do |value, index|
print " #{value.to_s.rjust(maxes[index])},"
end
puts
end
end
puts_arrays_columns(lists)
# Output:
# 123, SDLKFJSLDKFJSLDKFJLSDKJF,
# 123456, ffff,
y otra cosa
hashes = [
{ "id" => 123, "name" => "SDLKFJSLDKFJSLDKFJLSDKJF" },
{ "id" => 123456, "name" => "ffff" },
]
hash_maxes
def hash_maxes(hashes)
hashes.reduce({}) do |maxes, hash|
hash.keys.each do |key|
maxes[key] = [(maxes[key] || 0), key.to_s.length].max
maxes[key] = [(maxes[key] || 0), hash[key].to_s.length].max
end
maxes
end
end
hash_maxes(hashes)
# => {"id"=>6, "name"=>24}
puts_hashes_columns
def puts_hashes_columns(hashes)
maxes = hash_maxes(hashes)
return if hashes.empty?
# Headers
hashes.first.each do |key, value|
print " #{key.to_s.rjust(maxes[key])},"
end
puts
hashes.each do |hash|
hash.each do |key, value|
print " #{value.to_s.rjust(maxes[key])},"
end
puts
end
end
puts_hashes_columns(hashes)
# Output:
# id, name,
# 123, SDLKFJSLDKFJSLDKFJLSDKJF,
# 123456, ffff,
Editar: corrige las claves hash consideradas en la longitud.
hashes = [
{ id: 123, name: "DLKFJSDLKFJSLDKFJSDF", asdfasdf: :a },
{ id: 123456, name: "ffff", asdfasdf: :ab },
]
hash_maxes(hashes)
# => {:id=>6, :name=>20, :asdfasdf=>8}
¿Quieres incluir columnas columnas?
hashes.map{ |h| h.slice(:id, :name) }
# => [
# { id: 123, name: "DLKFJSDLKFJSLDKFJSDF" },
# { id: 123456, name: "ffff" },
#]
Estoy generando un script que está generando información en la consola. La información es algún tipo de estadística con un valor. Tanto como un hash.
Entonces, el nombre de un valor puede tener 8 caracteres de largo y otro es 3. cuando estoy realizando un bucle al dar salida a la información con dos / t algunas de las columnas no están alineadas correctamente.
Entonces, por ejemplo, la salida puede ser como tal:
long value name 14
short 12
little 13
tiny 123421
long name again 912421
Quiero que todos los valores estén alineados correctamente. En este momento estoy haciendo esto:
puts "#{value_name} - /t/t #{value}"
¿Cómo podría decir para los nombres largos, usar solo una pestaña? ¿O hay otra solución?
Hubo algunos errores antes, pero ahora puede usar la mayoría de la sintaxis de printf con% operator:
1.9.3-p194 :025 > " %-20s %05d" % [''hello'', 12]
=> " hello 00012"
Por supuesto, también puedes usar el ancho precalculado:
1.9.3-p194 :030 > "%-#{width}s %05x" % [''hello'', 12]
=> "hello 0000c"
Para futuras referencias y personas que lo miren o lo encuentren ... Use una gema. Sugiero https://github.com/wbailey/command_line_reporter
Por lo general, no desea utilizar pestañas, desea utilizar espacios y esencialmente configurar sus "columnas" usted mismo o de lo contrario se encuentra con este tipo de problemas.
Siempre que sepa que la longitud máxima no debe ser más de 20 caracteres:
printf "%-20s %s/n", value_name, value
Si quieres hacerlo más dinámico, algo así debería funcionar bien:
longest_key = data_hash.keys.max_by(&:length)
data_hash.each do |key, value|
printf "%-#{longest_key.length}s %s/n", key, value
end
String tiene una ljust para exactamente esto:
x = {"foo"=>37, "something long"=>42, "between"=>99}
x.each { |k, v| puts "#{k.ljust(20)} #{v}" }
# Outputs:
# foo 37
# something long 42
# between 99
O bien, si desea pestañas, puede hacer un poco de matemática (suponiendo que la pestaña muestre un ancho de 8) y escribir una breve función de visualización:
def tab_pad(label, tab_stop = 4)
label_tabs = label.length / 8
label.ljust(label.length + tab_stop - label_tabs, "/t")
end
x.each { |k, v| puts "#{tab_pad(k)}#{v}" }
# Outputs:
# foo 37
# something long 42
# between 99
Usualmente hay un tipo de esquema printf
%10s
que formatea muy bien.
Sin embargo, no he usado rubí en absoluto, así que debes verificarlo.
Sí, hay printf con formato.
El ejemplo anterior debe alinearse a la derecha en un espacio de 10 caracteres.
Puede formatear según su campo más amplio en la columna.
printf ([puerto,] formato, arg ...)
Imprime argumentos formateados según el formato como sprintf. Si el primer argumento es la instancia del IO o su subclase, imprima redirigido a ese objeto. el valor predeterminado es el valor de $ stdout.