ruby中的二维数组for循环有问题

时间:2021-05-15 21:34:39

I have studied C++, Java and I am learning Ruby now.
but It's hard to adapt to iteration in ruby for me yet.

我学过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

output of above code is as below

上面代码的输出如下所示

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

I thought it is like code as below in C

我认为它就像下面C中的代码

for(int i = 1; i<=2; i++)
   for(int j = 1; j<=n; j++)
       arys[i][j] = (i-1)*n+j

therefore, I expected the output will be like
[[0, 0, 0, 0, 0], [0, 1, 2, 3, 4], [0, 5, 6, 7, 8]]

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

what make the difference between above two codes?

这两个代码有什么区别?

2 个解决方案

#1


6  

In the very initialization line for arys you actually have created one inner array, referenced three times by arys outermost array:

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

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

__id__ above states for unique object identifier.

对于唯一的对象标识符,请在上面声明。

To achieve the behaviour you expected, one should produce three different arrays, e.g.:

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

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

Note dup above, that clones the object. Now we have three different objects (arrays)

上面的说明,复制对象。现在我们有三个不同的对象(数组)

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

and your code will work as expected.

您的代码将按照预期工作。

#2


1  

You can also take advantage of Array#new with a block, and use below code:

您也可以利用数组#new与块,并使用以下代码:

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

Here, we pass a block to outer array constructor so that we can create an array of size n+1 and default element values of 0 for sub-arrays (as needed in your problem statement).

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


Also, if you wish to use something other than for loop, here is one variant that will have same output:

另外,如果您希望使用其他的东西而不是for循环,这里有一个变量将具有相同的输出:

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

Note use of ... in 1...arys.size to use exclusive range. 1...10 is equivalent of to 1..9, in other words (1..9).to_a == (1...10).to_a will be true

注意使用……在1…氩。尺寸使用排他性范围。1……10等于1。换句话说(1..9)。to_a = =(1……10)。to_a将是真实的

#1


6  

In the very initialization line for arys you actually have created one inner array, referenced three times by arys outermost array:

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

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

__id__ above states for unique object identifier.

对于唯一的对象标识符,请在上面声明。

To achieve the behaviour you expected, one should produce three different arrays, e.g.:

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

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

Note dup above, that clones the object. Now we have three different objects (arrays)

上面的说明,复制对象。现在我们有三个不同的对象(数组)

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

and your code will work as expected.

您的代码将按照预期工作。

#2


1  

You can also take advantage of Array#new with a block, and use below code:

您也可以利用数组#new与块,并使用以下代码:

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

Here, we pass a block to outer array constructor so that we can create an array of size n+1 and default element values of 0 for sub-arrays (as needed in your problem statement).

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


Also, if you wish to use something other than for loop, here is one variant that will have same output:

另外,如果您希望使用其他的东西而不是for循环,这里有一个变量将具有相同的输出:

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

Note use of ... in 1...arys.size to use exclusive range. 1...10 is equivalent of to 1..9, in other words (1..9).to_a == (1...10).to_a will be true

注意使用……在1…氩。尺寸使用排他性范围。1……10等于1。换句话说(1..9)。to_a = =(1……10)。to_a将是真实的