ruby如何使用数组数组

时间:2013-11-08 08:51:37

标签: ruby arrays pass-by-reference pass-by-value

我正面对一些我不完全理解的事情。

我有一个数组,其元素是数组。

所以我有两个嵌套循环,在内循环中我填充我的内部数组 然后在外部循环中,我用内部数组填充外部数组。

arr=[]
mat=[]
for m in (0..1)
  for k in (0..1)
    arr[k]=rand.to_s
  end
  mat[m]=arr
end

最后我的矩阵充满了两个数组;每个数组都包含在上一次迭代中计算的值。 如果我希望矩阵中的第一个元素包含第一个计算数组,我必须在每个循环中重新初始化arr对象。 因此,似乎通过引用进行赋值,直到arr对象被“清理”。如果我添加

mat[m]=arr
arr=[]

所有工作都按预期工作:mat [0]将包含在第一个循环中计算的数组,mat [1]将包含在第二个循环中计算的数组。

这是设计还是不良副作用? 仅当我将数组指定为数组元素时才会发生这种情况。如果在循环中使用简单的字符串变量填充数组,则按预期方式进行。

我知道避免重用对象是一种很好的编程习惯,但这种行为无论如何都很奇怪。

3 个答案:

答案 0 :(得分:4)

您的问题是每次迭代都会覆盖您的arr变量的内容:arr[k]会覆盖已存在的任何内容。 arr变量需要是块的本地变量:

mat = []
2.times do             # avoid for... use iterators instead
  row = []
  2.times do 
    row << rand.to_s
  end
  mat << row
end

答案 1 :(得分:0)

我喜欢using hashes instead of multidimensional arrays的方法。

这个怎么样:

def creat­e_matrix x, y, conte­nt = nil, &block
  rows = (0...x­).to_a
  cols = (0...y­).to_a
  indices = rows.­product cols
  matrix = {}
  indices.ea­ch { |inde­x| matri­x[index] = ( block­_given? ? yield­( index ) : conte­nt ) }
  matrix
end

然后做:

matrix = create_matrix( 2, 2 ) { rand.to_s }

您将获得一个哈希,您可以像这样访问:

matrix[[0, 1]] #note the double brackets

答案 2 :(得分:0)

另一种方法:

(1..4).map{rand}.each_slice(2).to_a