我有:
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", "-", "-"]]
答案 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", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]