如何将数组作为值附加到另一个数组中而不作为引用?下面举例说明:
a = []
m = []
i = 1
# first loop
a[0] = i
a[1] = i + 1
m << a #=> [[1,2]]
i += 1
# second loop
a[0] = i
a[1] = i + 1
m << a #=> [[2,3],[2,3]]
我期待[[1,2],[2,3]]
之类的内容。
答案 0 :(得分:2)
将第一个m << a
替换为m << a.dup
。这会将dup
的副本(或a
许可)推送到m
,这与a
不同,因此当您修改a
时,您赢了&#39} ;修改m
中的对象。一种看待这种情况的方法如下:
a = []
m = []
m << a
a << 0
m #=> [[0]]
x = a.dup
m << x
m #=> [[0], [0]]
a << 1
m #=> [[0, 1], [0]]
x << 2
m #=> [[0, 1], [0, 2]]
答案 1 :(得分:2)
您可以通过检查各种对象的ID来更好地了解这里发生了什么。
a = []
a.object_id #=> 2164985760
m = []
i = 1
第一次循环
a[0] = i #=> 1
a[1] = i + 1 #=> 2
a.object_id #=> 2164985760
m << a #=> [[1,2]]
m.object_id #=> 2165031720
m[0].object_id #=> 2164985760
第二次循环
i += 1
a[0] = i #=> 2
a[1] = i + 1 #=> 3
a.object_id #=> 2164985760
m << a #=> [[2, 3], [2, 3]]
m.object_id #=> 2165031720
m[0].object_id #=> 2164985760
m[1].object_id #=> 2164985760
现在让我们再试一次,只需一次更改。正如@sawa建议的那样,在第二个循环之前添加a = []
。 (以下对象ID当然会与上面的不同。)
a = []
a.object_id #=> 2164690760
m = []
i = 1
第一次循环
a[0] = i #=> 1
a[1] = i + 1 #=> 2
a.object_id #=> 2164690760
m << a #=> [[1, 2]]
m.object_id #=> 2164655180
m[0].object_id #=> 2164690760
第二次循环
a = []
a.object_id #=> 2161060600
i += 1 #=> 2
a[0] = i #=> 2
a[1] = i + 1 #=> 3
a.object_id #=> 2161060600
m << a #=> [[1, 2], [2, 3]]
m.object_id #=> 2164655180
m[0].object_id #=> 2164690760
m[1].object_id #=> 2161060600
答案 2 :(得分:1)
将a
分配给另一个阵列。
m = []
i = 1
a = []
a[0] = i
a[1] = i + 1
m << a
i += 1
a = []
a[0] = i
a[1] = i + 1
m << a
答案 3 :(得分:0)
如果您在循环后期望得到类似[[1,2],[2,3]]
的内容,那么您可能应该使用.map
的Ruby功能来循环并返回一个数组。
这样你就不用担心管理中间变量(甚至是你的例子中的计数器):
loop_count = 2 # or whatever currently determines how many loops you make
m = (1..loop_count).map do |i|
[i, i+1]
end
m #=> [[1,2],[2,3]]