我学过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]]
上述两个代码的区别是什么?
答案 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_a
将true