很好地格式化输出到控制台,指定选项卡的数量
我正在生成将信息输出到控制台的脚本。 这些信息是某种有价值的统计数据。 非常像一个哈希。
所以一个值的名字可能是8个字符长,另一个是3.当我循环输出信息与两个\ t一些列没有正确alignment。
所以例如输出可能是这样的:
long value name 14 short 12 little 13 tiny 123421 long name again 912421 我想要所有的值正确排列。 现在我正在这样做:
 puts "#{value_name} - \t\t #{value}" 
我怎么能说长名,只使用一个选项卡? 还是有另一种解决scheme?
 通常有一个%10s的printfscheme,格式很好。 
 但是,我还没有使用ruby,所以你需要检查。 
 是的,有格式的printf。 
 上面的例子应该在10个字符的空间里alignment。 
 您可以根据列中最宽的字段进行格式化。 
printf([port,]格式,arg …)
打印根据像sprintf这样的格式格式化的参数。 如果第一个参数是IO或其子类的实例,则打印redirect到该对象。 默认值是$ stdout的值。
只要你知道最大长度不超过20个字符:
 printf "%-20s %s\n", value_name, value 
如果你想使它更加dynamic,像这样的东西应该很好地工作:
 longest_key = data_hash.keys.max_by(&:length) data_hash.each do |key, value| printf "%-#{longest_key.length}s %s\n", key, value end 
之前几乎没有错误,但现在可以使用%运算符来使用大部分的printf语法:
 1.9.3-p194 :025 > " %-20s %05d" % ['hello', 12] => " hello 00012" 
当然你也可以使用预先计算的宽度:
 1.9.3-p194 :030 > "%-#{width}s %05x" % ['hello', 12] => "hello 0000c" 
string有一个内置的正是这个:
 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 
或者,如果你想要标签,你可以做一个小math(假设标签显示宽度为8),并写一个简短的显示function:
 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 
我写了一个东西
- 自动检测列宽
- 空间与空间
-  数组[[],[],...]或散列数组[{},{},...]
- 
控制台窗口不检测列太宽 列表= [[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, 
还有一件事
 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, 
编辑:修复在长度考虑的散列键。
 hashes = [ { id: 123, name: "DLKFJSDLKFJSLDKFJSDF", asdfasdf: :a }, { id: 123456, name: "ffff", asdfasdf: :ab }, ] hash_maxes(hashes) # => {:id=>6, :name=>20, :asdfasdf=>8} 
想要将列列入白名单?
 hashes.map{ |h| h.slice(:id, :name) } # => [ # { id: 123, name: "DLKFJSDLKFJSLDKFJSDF" }, # { id: 123456, name: "ffff" }, #] 
为了将来的参考和人谁看着这个或find它…使用gem。 我build议https://github.com/wbailey/command_line_reporter
你通常不想使用制表符,你想使用空格,并基本上设置你的“列”你自己,否则你碰到这些types的问题。