Ruby数组赋值会产生意外结果

时间:2018-02-28 01:32:02

标签: ruby

我有:

a = [['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-']]
b = [['-'] * 3] * 3 # => [["-", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]
a == b #=> true

似乎没错。

a[0][0] = 'X'
a # => [["X", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]

b[0][0] = 'X'
b # => [["X", "-", "-"], ["X", "-", "-"], ["X", "-", "-"]]

a == b # => false

什么?为什么b[0][0] = 'X'会在三个地方更改值?

我也发现它不会这样:

b = [%w[- - -]] * 3 # => [["-", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]
b[0][0] = 'X'
b # => [["X", "-", "-"], ["X", "-", "-"], ["X", "-", "-"]]

3 个答案:

答案 0 :(得分:2)

此:

[object]*3

将创建一个包含3个同一对象引用的数组,因此更改其中一个会改变所有这些对象,如下所示:

a = [[1]]*3 #=> [[1], [1], [1]]
a[0][0] = 2 #=> [[2], [2], [2]]

如果您希望使用3个不同的对象创建长度为3的数组,请执行以下操作:

a = 3.times.map {[1]} #=> [[1], [1], [1]]
a[0][0] = 2           #=> [[2], [1], [1]]

答案 1 :(得分:1)

您创建的第一个初始化3个嵌套在1中的数组。

varchar

第二次初始化你创建了1个数组,然后指向同一个数组3次。

a = [['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-']]
#   [['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-']] 
#         ARRAY a          ARRAY b          ARRAY c

如果你改变b [0] [0]就这样思考将只改变一个数组,但是你可以给人的印象就是改变了更多的数组,因为它被多次引用。

你可以自己检查一下它们的地址。

b = [['-'] * 3] * 3
#   [['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-']] 
#         ARRAY x          ARRAY x          ARRAY x

答案 2 :(得分:0)

我发现必须这样做:

irb(main):001:0> b = Array.new(3) { Array.new(3) { '-' } }
=> [["-", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]
irb(main):002:0> b[0][0] = 'X'
=> "X"
irb(main):003:0> b
=> [["X", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]
相关问题