Tengo:

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

Parece correcta

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

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

a == b # => false

¿Qué? ¿Por qué b[0][0] = 'X' cambia los valores en tres lugares?

También descubrí que no funciona de esta manera:

b = [%w[- - -]] * 3 # => [["-", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]
b[0][0] = 'X'
b # => [["X", "-", "-"], ["X", "-", "-"], ["X", "-", "-"]]
-1
gdonald 28 feb. 2018 a las 04:32

3 respuestas

La mejor respuesta

Descubrí que tiene que hacerse de esta manera:

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", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]]
0
gdonald 28 feb. 2018 a las 01:47

Éste:

[object]*3

Creará una matriz con 3 referencias al mismo objeto, por lo que cambiar una de ellas las cambia a todas de la siguiente manera:

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

Si desea crear una matriz de longitud 3 con 3 objetos diferentes, haga esto:

a = 3.times.map {[1]} #=> [[1], [1], [1]]
a[0][0] = 2           #=> [[2], [1], [1]]
2
Asone Tuhid 28 feb. 2018 a las 01:52

La primera inicialización que creó 3 matrices anidadas en 1.

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

La segunda inicialización creó 1 matriz, y luego apuntó la misma matriz 3 veces.

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

Pensar de esta manera si cambia b [0] [0] va a alterar solo una matriz, sin embargo, puede tener la impresión de que está cambiando más matrices porque está siendo referenciada muchas veces.

Puede verificarlo usted mismo imprimiendo las direcciones de ellos.

puts a[0].object_id # 47369457807480
puts a[1].object_id # 47369457807320
puts a[2].object_id # 47369457807200

puts b[0].object_id # 47369457807070
puts b[1].object_id # 47369457807070
puts b[2].object_id # 47369457807070
1
Kandy 28 feb. 2018 a las 03:49