2016-11-07 45 views
0

我試圖把一個整數數組(最終被轉換成他們的ASCII字符)成一個數組,由星星框架,但它只是不工作,我不知道爲什麼。如何將2D數組插入另一個2D數組? (紅寶石)

我的代碼在下面,數據是一個包含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

當試圖運行你的代碼時,我得到了''未定義的局部變量或方法'data'''。請修復它,並且還包括當前(錯誤)輸出和預期(正確)結果。 – Stefan

+0

如果我添加'data = Array.new(24){Array.new(42,' - ')}'那麼它可以工作,儘管輸出是非常原始的。 – 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。爲了簡單起見,我假設data具有6元素(「行」),每個元素是4元素的數組(形成「列」,儘管Ruby實際上沒有包含行和列的數組的概念)。

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 

返回上面的結果。