まずはdata
を作ってみましょう。簡単にするため、data
は6
要素( "行")を持ち、各要素は4
要素の配列です(実際には行と列を持つ配列の概念はありません)。
ROWS = 6
COLS = 4
data = (ROWS*COLS).times.to_a.each_slice(4).to_a
#=> [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15],
# [16, 17, 18, 19], [20, 21, 22, 23]]
ここで、コードを少し修正して、望ましい結果を得ることができます。次のようにこれを行うの
rows = data.size+2
#=> 8
cols = data.first+2
#=> 6
image = Array.new(rows) { Array.new(cols, ' ')}
(0...rows).each do |r| # note 3 dots here and below
if r == 0 || r == rows-1
(0...cols).each do |c|
image[r][c] = '*'
end
else
(0...cols).each do |c|
if c == 0 || c == cols-1
image[r][c] = '*'
else
image[r][c] = data[r-1][c-1]
end
end
end
end
image.each { |row| p row }
プリント
["*", "*", "*", "*", "*", "*"]
["*", 0, 1, 2, 3, "*"]
["*", 4, 5, 6, 7, "*"]
["*", 8, 9, 10, 11, "*"]
["*", 12, 13, 14, 15, "*"]
["*", 16, 17, 18, 19, "*"]
["*", 20, 21, 22, 23, "*"]
["*", "*", "*", "*", "*", "*"]
よりルビーのような方法があります。
image = [['*']*(data.first.size+1)]
ROWS.times { |i| image << ['*', *data[i], '*'] }
image << image.first
image.each { |row| p row }
代わりにきれいにフォーマットされた表を作成したい場合は、次のようにします。
def fmt(data, col_space, boundary_char='*')
col_width = data.flatten.map { |n| n.to_s.size }.max + col_space
nrows, ncols = data.size, data.first.size
header = boundary_char * (col_width * ncols + 2 + col_space)
right_border = " "*col_space << boundary_char
image = [header]
data.each { |row|
image << "%s%s%s" %
[boundary_char, row.map { |n| n.to_s.rjust(col_width) }.join, right_border] }
image << header
image
end
puts fmt(data, 2)
プリント
********************
* 0 1 2 3 *
* 4 5 6 7 *
* 8 9 10 11 *
* 12 13 14 15 *
* 16 17 18 19 *
* 20 21 22 23 *
********************
次のように(上記で定義した通りdata
)手順です。
そして
col_space = 2
boundary_char='*'
a = data.flatten
#=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
# 15, 16, 17, 18, 19, 20, 21, 22, 23]
b = a.map { |n| n.to_s.size }
#=> [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
col_width = b.max + col_space
#=> 2 + 2 => 4
nrows, ncols = data.size, data.first.size
#=> [6, 4]
header = boundary_char * (col_width * ncols + 2 + col_space)
#=> * * (4*4 + 2 + 2)
#=> "********************"
right_border = " "*col_space << boundary_char
#=> " "*2 << "*" =< " " << "*" => " *"
image = [header]
#=> ["********************"]
data.each { |row|
puts "row=#{row}"
puts " image row=#{"%s%s%s" % [boundary_char,
row.map { |n| n.to_s.rjust(col_width) }.join, right_border]}"
image << "%s%s%s" % [boundary_char,
row.map { |n| n.to_s.rjust(col_width) }.join, right_border] }
row=[0, 1, 2, 3]
image row=* 0 1 2 3 *
row=[4, 5, 6, 7]
image row=* 4 5 6 7 *
row=[8, 9, 10, 11]
image row=* 8 9 10 11 *
row=[12, 13, 14, 15]
image row=* 12 13 14 15 *
row=[16, 17, 18, 19]
image row=* 16 17 18 19 *
row=[20, 21, 22, 23]
image row=* 20 21 22 23 *
image << header
image
以上の結果を返します。
コードを実行しようとすると、 ''未定義のローカル変数またはメソッド ''データ '''が返されます。それを修正し、現在の(間違った)出力と予想される(正しい)結果も含めてください。 – Stefan
'data = Array.new(24){Array.new(42、 ' - ')}'を追加すると、出力は実際にはrawですが、動作します。 – tadman