在ruby中使用2D数组for循环的麻烦

时间:2016-01-26 11:51:11

标签: ruby for-loop multidimensional-array

我学过C ++,Java,现在我正在学习Ruby。
但对我而言,很难适应ruby中的迭代。

n = 4
arys = Array.new(3, Array.new(n+1, 0))

for i in 1..2
    for j in 1..n
        arys[i][j] = (i-1)*n+j
    end
end

p arys
  

以上代码的输出如下

[[0, 5, 6, 7, 8], [0, 5, 6, 7, 8], [0, 5, 6, 7, 8]]

我认为这就像C

中的代码一样
for(int i = 1; i<=2; i++)
   for(int j = 1; j<=n; j++)
       arys[i][j] = (i-1)*n+j
  

因此,我预计输出将像
一样        [[0, 0, 0, 0, 0], [0, 1, 2, 3, 4], [0, 5, 6, 7, 8]]

上述两个代码的区别是什么?

2 个答案:

答案 0 :(得分:6)

arys的初始化行中,您实际创建了一个内部数组,引用了三次 arys最外层数组:

arys.map &:__id__
#⇒ [
#  [0] 28193580,
#  [1] 28193580,
#  [2] 28193580
# ]

__id__高于unique object identifier的状态。

为了实现您期望的行为,应该生成三个不同的数组,例如:

ary = Array.new(5, 0)
arys = 3.times.map { ary.dup }

注意上面dup克隆对象。现在我们有三个不同的对象(数组)

arys.map &:__id__
#⇒ [
#  [0] 34739980,
#  [1] 34739920,
#  [2] 34739860
# ]

您的代码将按预期工作。

答案 1 :(得分:1)

你也可以利用Array#new一个块,并使用下面的代码:

arys = Array.new(3) {Array.new(n+1, 0)}

这里,我们将一个块传递给外部数组构造函数,这样我们就可以为子数组创建一个大小为n+1且默认元素值为0的数组(根据问题语句的需要)。

另外,如果你想使用for循环以外的东西,这里有一个变量具有相同的输出:

(1...arys.size).each do |i|
    (1..n).each do |j|
        arys[i][j] = (i-1)*n + j
    end
end

请注意...中使用1...arys.size来使用独占范围。 1...10相当于1..9,换句话说(1..9).to_a == (1...10).to_atrue