我有一个数组:
animals = [
["cats", "dogs"],
["verrylongcat", "dog"],
["shortcat", "verrylongdog"],
["cat", "dog"]
]
我想很好地展示它。是否有一种简单的方法可以使柱子固定宽度,所以我得到这样的东西:
cats dogs
verrylongcat dog
shortcat verrylongdog
cat dog
animals
只是一个例子,我的数组也可能有3列,4列甚至更多。
答案 0 :(得分:5)
您正在寻找String#ljust
:
max_cat_size = animals.map(&:first).max_by(&:size).size
animals.each do |cat, dog|
puts "#{cat.ljust(max_cat_size)} #{dog}"
end
如果您想要多个空格,只需在插值中添加相应的数量。
假设你的阵列是 n×m 而不是 2×m :
animal_max_sizes = animals.first.size.times.map do |index|
animals.transpose[index].map(&:to_s).max_by(&:size).size
end
animals.map do |animal_line|
animal_line.each.with_index.reduce('') do |animal_line, (animal, index)|
animal_line + animal.to_s.ljust(animal_max_sizes[index].next)
end
end.each { |animal_line_stringified| puts animal_line_stringified }
注意:如果您的数组包含to_s
个,数字等,则会使用nil
。
答案 1 :(得分:4)
另一种方法是使用printf样式格式化。如果您知道每行中总是只有2个单词,那么您可以这样做:
#!/usr/bin/env ruby
lines = [
' cats dogs',
' verrylongcat dog',
'shortcat verrylongdog ',
' cat dog ',
]
lines.map(&:strip).each do |line|
puts "%-14s%s" % line.split
end
输出:
cats dogs
verrylongcat dog
shortcat verrylongdog
cat dog
如果您需要根据数据计算列宽,那么您还需要做更多的工作:
# as @ndn showed:
first_col_width = lines.map(&:split).map(&:first).max_by(&:size).size + 2
lines.map(&:strip).each do |line|
puts "%-#{first_col_width}s%s" % line.split
end
答案 2 :(得分:1)
这是另一种可变数量列的尝试。给定这个数组:
animals = [
['Cats', 'Dogs', 'Fish'],
['Mr. Tinkles', 'Buddy', 'Nemo'],
['Calico', 'Butch', 'Marlin'],
['Ginger', 'Ivy', 'Dory']
]
我们可以通过transpose
,map
,length
和max
来计算每列的宽度:
widths = animals.transpose.map { |x| x.map(&:length).max }
#=> [11, 5, 6]
基于此,我们可以生成一个格式字符串,可以传递给sprintf
(或其快捷方式%
):
row_format = widths.map { |w| "%-#{w}s" }.join(' ')
#=> "%-11s %-5s %-6s"
%s
表示字符串参数,11
,5
和6
是我们的宽度,-
左对齐结果。
我们试一试:
row_format % animals[0] #=> "Cats Dogs Fish "
row_format % animals[1] #=> "Mr. Tinkles Buddy Nemo "
row_format % animals[2] #=> "Calico Butch Marlin"
看起来不错,我们应该使用一个循环并将其包装在一个方法中:
def print_table(array)
widths = array.transpose.map { |x| x.map(&:length).max }
row_format = widths.map { |w| "%-#{w}s" }.join(' ')
array.each do |row_values|
puts row_format % row_values
end
end
print_table(animals)
输出:
Cats Dogs Fish
Mr. Tinkles Buddy Nemo
Calico Butch Marlin
Ginger Ivy Dory
稍微调整一下,您还可以输出MySQL样式表:
def print_mysql_table(array)
widths = array.transpose.map { |x| x.map(&:length).max }
row_format = '|%s|' % widths.map { |w| " %-#{w}s " }.join('|')
separator = '+%s+' % widths.map { |w| '-' * (w+2) }.join('+')
header, *rows = array
puts separator
puts row_format % header
puts separator
rows.each do |row_values|
puts row_format % row_values
end
puts separator
end
print_mysql_table(animals)
输出:
+-------------+-------+--------+
| Cats | Dogs | Fish |
+-------------+-------+--------+
| Mr. Tinkles | Buddy | Nemo |
| Calico | Butch | Marlin |
| Ginger | Ivy | Dory |
+-------------+-------+--------+