Looping through a 2d array in ruby to display it in a table format?
How can i represent a 2d array in a table format in the terminal, where it lines up the colu开发者_Python百科mns properly just like a table?
so it looks like so:
1 2 3 4 5
1 [ Infinity | 40 | 45 | Infinity | Infinity ]
2 [ Infinity | 20 | 50 | 14 | 20 ]
3 [ Infinity | 30 | 40 | Infinity | 40 ]
4 [ Infinity | 28 | Infinity | 6 | 6 ]
5 [ Infinity | 40 | 80 | 12 | 0 ]
instead of:
[ Infinity,40,45,Infinity,Infinity ]
[ Infinity,20,50,14,20 ]
[ Infinity,30,40,Infinity,40 ]
[ Infinity,28,Infinity,6,6 ]
[ Infinity,40,80,12,0 ]
a = [[Infinity, 40, 45, Infinity, Infinity],
[Infinity, 20, 50, 14, 20 ],
[Infinity, 30, 40, Infinity, 40 ],
[Infinity, 28, Infinity, 6, 6 ],
[Infinity, 40, 80, 12, 0 ]]
Step by Step Explanation
You first need to acheive the column width. col_width
below is an array that gives the width for each column.
col_width = a.transpose.map{|col| col.map{|cell| cell.to_s.length}.max}
Then, this will give you the main part of the table:
a.each{|row| puts '['+
row.zip(col_width).map{|cell, w| cell.to_s.ljust(w)}.join(' | ')+']'}
To give the labels, do the following.
puts ' '*(a.length.to_s.length + 2)+
(1..a.length).zip(col_width).map{|i, w| i.to_s.center(w)}.join(' ')
a.each_with_index{|row, i| puts "#{i+1} ["+
row.zip(col_width).map{|cell, w| cell.to_s.ljust(w)}.join(' | ')+
']'
}
All in One This is for ruby1.9. Small modification shall make it work on ruby 1.8.
a
.transpose
.unshift((1..a.length).to_a) # inserts column labels #
.map.with_index{|col, i|
col.unshift(i.zero?? nil : i) # inserts row labels #
w = col.map{|cell| cell.to_s.length}.max # w = "column width" #
col.map.with_index{|cell, i|
i.zero?? cell.to_s.center(w) : cell.to_s.ljust(w)} # alligns the column #
}
.transpose
.each{|row| puts "[#{row.join(' | ')}]"}
Try this:
a = [['a', 'b', 'c'], ['d', 'e', 'f']]
puts a.map{|e| "[ %s ]" % e.join(",")}.join("\n")
Edit:
Extended the answer based on additional request.
a = [
[ "Infinity",40,45,"Infinity","Infinity" ],
[ "Infinity",20,50,14,20 ],
[ "Infinity",30,40,"Infinity",40 ],
[ "Infinity",28,"Infinity",6,6 ],
[ "Infinity",40,80,12,0 ]
]
def print_2d_array(a, cs=12)
report = []
report << " " * 5 + a[0].enum_for(:each_with_index).map { |e, i|
"%#{cs}s" % [i+1, " "]}.join(" ")
report << a.enum_for(:each_with_index).map { |ia, i|
"%2i [ %s ]" % [i+1, ia.map{|e| "%#{cs}s" % e}.join(" | ") ] }
puts report.join("\n")
end
Output
Now calling print_2d_array(a)
produces the result below. You can increase the column size based on your requirement.
1 2 3 4 5
1 [ Infinity | 40 | 45 | Infinity | Infinity ]
2 [ Infinity | 20 | 50 | 14 | 20 ]
3 [ Infinity | 30 | 40 | Infinity | 40 ]
4 [ Infinity | 28 | Infinity | 6 | 6 ]
5 [ Infinity | 40 | 80 | 12 | 0 ]
a = [['a', 'b', 'c'], ['d', 'e', 'f']]
a.each {|e| puts "#{e.join ", "}\n"}
Not the simplest way maybe, but works
a, b, c
d, e, f
Well, if I was doing it, I would go:
require 'pp'
pp my_2d_array
But if this is homework, I suppose that won't work. Perhaps:
puts a.inject("") { |m, e| m << e.join(' ') << "\n" }
精彩评论