在ruby中循环通过2d数组以表格式显示?

在ruby中循环通过2d数组以表格式显示?,ruby,Ruby,如何在终端中以表格格式表示二维数组,使列像表格一样正确排列 看起来是这样的: 1 2 3 4 5 1 [ Infinity | 40 | 45 | Infinity | Infinity ] 2 [ Infinity | 20 | 50 | 14 | 20 ] 3 [ Infinity | 30 | 40 | Infinity | 40 ] 4 [

如何在终端中以表格格式表示二维数组,使列像表格一样正确排列

看起来是这样的:

         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 ]
而不是:

[ 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, b, c
d, e, f

如果我在做的话,我会:

require 'pp'
pp my_2d_array
但如果这是家庭作业,我想那是行不通的。也许:

puts a.inject("") { |m, e| m << e.join(' ') << "\n" }
放置a.inject(“”{| m,e | m试试这个:

a = [['a', 'b', 'c'], ['d', 'e', 'f']]
puts a.map{|e| "[ %s ]" % e.join(",")}.join("\n")
编辑:

根据其他请求扩展答案

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
逐步解释

首先需要确定列宽。
col\u width
下面是一个数组,给出每列的宽度

col_width = a.transpose.map{|col| col.map{|cell| cell.to_s.length}.max}
然后,这将为您提供表格的主要部分:

a.each{|row| puts '['+
 row.zip(col_width).map{|cell, w| cell.to_s.ljust(w)}.join(' | ')+']'}
要给出标签,请执行以下操作

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(' | ')+
    ']'
}
一体机这是针对ruby1.9的。稍加修改即可在ruby1.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(' | ')}]"}

以前从未听说过预打印,但它似乎对数组产生了与普通
p
@Nikita相同的结果,你只是没有尝试过一个复杂的例子。它会比
p
做得更好,比如说,
pp([t=%w{how now brown cow},t,t])
这似乎对2d数组有效,我得到了
irb(main):001:0>require'pp'=>true-irb(main):002:0>d=[[2,3,4],[2,6,9]=>[[2,3,4],[2,6,9]]irb(main):003:0>pp-d[[2,3,4],[2,6,9]=>nil-irb(main):004:0>d=>[2,3,4],[2,6,9]]irb(main):005:0>
@Mo,这不是
#pretty#u print
API的工作方式,它的数据参数必须是单个参数,如果给它第二个或第三个参数,它将使用它们作为输出IO对象和页面宽度。该API在Ruby标准库中有文档记录。@DigitalRoss好的,我明白了窍门。它在一行中打印两行数组,但对于3行或更多行,它会将每一行放在单独的行中。技巧,技巧,技巧。嗨,有没有办法将其放入实际表中?我更新了我的问题作为示例。谢谢嗨,有没有办法将其放入实际表中?我更新了我的问题作为示例。谢谢嗨,谢谢你的回答,但它给了我一个:
未定义的方法`w[0,20,5,无穷大,无穷大]:数组(NoMethodError)
im使用ruby 1.8.*非常感谢你的工作,但是只有一个问题,我如何为行和列添加标签?就像问题中的示例一样。你,我的新朋友,问了一个惊人的问题!
a.each{|row| puts '['+
 row.zip(col_width).map{|cell, w| cell.to_s.ljust(w)}.join(' | ')+']'}
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(' | ')+
    ']'
}
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(' | ')}]"}