ruby如何处理数组数组

ruby如何处理数组数组,ruby,arrays,pass-by-reference,pass-by-value,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=[]
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]将包含在第二个循环中计算的数组

这是故意的还是不希望的副作用? 只有将数组指定为数组元素时,才会发生这种情况。如果在循环中用简单的字符串变量填充数组,所有操作都会按预期进行


我知道避免重用对象是一种很好的编程实践,但这种行为很奇怪。

您的问题是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

您的问题是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
我喜欢这种方法

这个怎么样:

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
我喜欢这种方法

这个怎么样:

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

另一种方法是:

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

另一种方法是:

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

@尼尔:事实上,这或多或少就是我的意思。不过,我的非母语英语可能会碍事我已经用一种希望更好的方式重新表述了它。是的,我认为现在删除我的评论和+1已经足够好了-ed@Denis:谢谢,我已经发现这就是它的工作方式。问题是它是否正确。我希望每次我做mat@Denis:也许现在我明白了。这是一个变量范围的问题。在两个循环之外声明行是错误的。@kranz:是的,您的具体问题是范围界定。关于在mat=或mat[m]=中添加的内容,您总是向对象添加指针。如果没有正确的作用域,您最终会引用同一行两次,您可以通过运行它来了解这一点。@Niel:实际上,这或多或少就是我的意思。不过,我的非母语英语可能会碍事我已经用一种希望更好的方式重新表述了它。是的,我认为现在删除我的评论和+1已经足够好了-ed@Denis:谢谢,我已经发现这就是它的工作方式。问题是它是否正确。我希望每次我做mat@Denis:也许现在我明白了。这是一个变量范围的问题。在两个循环之外声明行是错误的。@kranz:是的,您的具体问题是范围界定。关于在mat=或mat[m]=中添加的内容,您总是向对象添加指针。如果没有适当的作用域,最终将引用同一行两次,通过运行它可以看到这一点。