ruby 如何与数组数组一起工作 [已关闭]

How does ruby works with array of arrays [closed]

提问人:kranz 提问时间:11/8/2013 更新时间:11/8/2013 访问量:158

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

9年前关闭。

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

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

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

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] 将包含第二个循环中计算的数组。

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

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

Ruby 数组 按引用传递

评论


答:

4赞 Denis de Bernardy 11/8/2013 #1

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

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

评论

0赞 Denis de Bernardy 11/8/2013
@Niel:实际上,这或多或少是我的意思。不过,我的非母语英语可能会妨碍我。;-)我以一种希望更好的方式重新表述了它。
0赞 Neil Slater 11/8/2013
是的,我认为现在我已经足够好了,因为我删除了我的评论并 +1-ed
0赞 kranz 11/8/2013
@Denis:谢谢,我已经发现这就是它的工作方式。问题是它是否正确。我希望每次我做 mat << row 时,都会添加一个 row 副本作为 mat 的新元素。仅当在每次迭代时重新初始化行时,才会发生这种情况。否则,mat 会添加指向行的指针,而不是 is content。我错了吗?
0赞 kranz 11/8/2013
@Denis:也许现在我明白了。这是一个可变范围的问题。在两个循环之外声明行是错误的。
0赞 Denis de Bernardy 11/8/2013
@kranz:是的,你的具体问题是范围界定。关于在 or 中添加的内容,您总是在添加指向对象的指针。如果没有适当的范围,您最终会两次引用同一行,您可以通过漂亮的打印来运行它来查看这一点。mat =mat[m] =
0赞 Conkerchen 11/8/2013 #2

我喜欢使用哈希而不是多维数组的方法。

这个怎么样:

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
0赞 hirolau 11/8/2013 #3

另一种方法:

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