如何将2D阵列插入另一个2D阵列? (红宝石)

时间:2016-11-07 15:01:40

标签: arrays ruby

我正在尝试将一个整数数组(最终被转换为它们的ASCII字符)放入一个数组中,由星星构成,但它不起作用,我不知道为什么。

我的代码如下,数据是一个包含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

3 个答案:

答案 0 :(得分: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

实际上,克隆数据然后向其添加边框可能更容易。毕竟,你在这里所做的一切,都可能是你所遇到的问题的根源。

答案 1 :(得分: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, "*"], ["*", "*", "*", "*", "*", "*", "*", "*", "*", "*"]]

答案 2 :(得分:0)

让我们先构建data。为简单起见,我假设data6个元素("行"),每个元素都是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, "*"]
["*", "*", "*", "*", "*", "*"]

更像Ruby的方法如下:

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   

返回上面的结果。