2016-11-07 15 views
0

私は星の枠で囲まれた配列に(最終的にはASCII文字に変換される)整数の配列を入れようとしていますが、それはうまくいかず、理由はわかりません。2D配列を別の2D配列に挿入するにはどうすればよいですか? (Ruby)

私のコードは以下で、データは40列と22行を含む配列です。

image = Array.new(24) { Array.new(42, ' ')} 
(0..23).each do |r| 
    if r == 0 || r == 23 then 
    (0..41).each do |c| 
     image[r][c] = '*' 
    end 
    else 
    (0..41).each do |c| 
     if c == 0 || c == 41 then 
     image[r][c] = '*' 
     else 
     image[r][c] = data[r][c] 
     end 
    end 
    end  
end 


print image 
+0

コードを実行しようとすると、 ''未定義のローカル変数またはメソッド ''データ '''が返されます。それを修正し、現在の(間違った)出力と予想される(正しい)結果も含めてください。 – Stefan

+0

'data = Array.new(24){Array.new(42、 ' - ')}'を追加すると、出力は実際にはrawですが、動作します。 – tadman

答えて

0

あなたはこのように複雑すぎます。ステップに分割してください。ネストされたループと条件文を削除します。

1)イメージの行0と23をグラブし、すべてを「*」に設定します。

2)各行(すなわちimage.each do |row| ...)を繰り返し、列0と41を「*」に設定します。

3)各行をもう一度繰り返し、データ内のものと一致するように他の列を設定します(ここではネストされたループがおそらく必要ですが、条件はありません)。

編集:完全なコードは次のようになり可能性は:

#step0 -- create nested array with first and last rows missing. Doesn't need useless spaces. Nil instead. 
image = Array.new(22) { Array.new(42) } 

#step1 --- iterate through the rows and set first and last columns to "*" 
image.each do |row| 
    row[0] = "*" 
    row[41] = "*" 
end 

#step2 -- add first and last rows, which are all "*" 
image.shift(Array.new(42, "*")) 
image.push(Array.new(42, "*")) 

#step3 -- nested loop that matches image to data only if not already set. 
image.each_with_index do |row, ridx| 
    row.each_with_index do |col, cidx| 
    image[row][col] = data[row][col] unless image[row][col] 
    end 
end 

実際にはデータのクローンを作成し、それにその境界線を追加する方が簡単かもしれません。つまり、結局あなたがここでやっていることで、あなたが抱えている問題の原因かもしれません。

+0

私はステップ2と3を実際に理解していませんか?あなたはさらに説明できますか? – twigface

+0

これは私がステップ2のためにやっていることです: 'image.each do | row | image [row] [0] = "*" image [row] [23] = "*" end' – twigface

0

私はあなたのケースの権利を理解し、あなたは次の値がある場合:

image = Array.new(5) { Array.new(10, ' ')} 
data = [[0, 1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, 14, 15], [16, 17, 18, 19, 20, 21, 22, 23]] 

を次に、あなたのコードの最小の編集は次のようになります必要があります。

(0..4).each do |r| 
    (0..9).each do |c| 
    if r == 0 || r == 4 || c == 0 || c == 9 
     image[r][c] = '*' 
    else 
     image[r][c] = data[r.pred][c.pred] 
    end 
    end 
end 

その後の意志を引き起こすようになっています

> image 
#=> [["*", "*", "*", "*", "*", "*", "*", "*", "*", "*"], ["*", 0, 1, 2, 3, 4, 5, 6, 7, "*"], ["*", 8, 9, 10, 11, 12, 13, 14, 15, "*"], ["*", 16, 17, 18, 19, 20, 21, 22, 23, "*"], ["*", "*", "*", "*", "*", "*", "*", "*", "*", "*"]] 
+0

これは私のデータではありません。どのように私のコードは動作しませんか? – twigface

+0

@twigfaceあなたは 'data'の値を追加しません –

0

まずはdataを作ってみましょう。簡単にするため、data6要素( "行")を持ち、各要素は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 

以上の結果を返します。

関連する問題