2012-05-31 16 views
6

Tengo una matriz en Ruby que consta de 5 matrices vacías. Estoy intentando utilizar el operador << para insertar una cadena en la primera matriz, pero el resultado es que la cadena se inserta en TODAS las matrices. Por favor, ayúdame a entender esto.Al insertar una cadena en una matriz dentro de una matriz se obtiene un resultado inesperado

El resultado esperado es:

# => [["car"], [], [], [], []] 

pero en cambio me sale:

# => [["car"], ["car"], ["car"], ["car"], ["car"]] 

volcado IRB:

1.9.3-p194 :001 > output = Array.new(5, []) 
=> [[], [], [], [], []] 
1.9.3-p194 :002 > output.inspect 
=> "[[], [], [], [], []]" 
1.9.3-p194 :003 > output[0].inspect 
=> "[]" 
1.9.3-p194 :004 > output[0] << "car" 
=> ["car"] 
1.9.3-p194 :005 > output.inspect 
=> "[[\"car\"], [\"car\"], [\"car\"], [\"car\"], [\"car\"]]" 
+0

posible duplicado de [¿Por qué doesn 'manera tersa de definir nuevos hash en el trabajo de Ruby (todos se refieren al mismo o bject)] (http://stackoverflow.com/questions/7540084/why-doesnt-terse-way-of-defining-new-hashes-in-ruby-work-they-all-refer-to-sam) –

+0

Gracias ¡todas! Esto me estaba DETENIENDO REALMENTE. Y ahora aprendí un nuevo método: object_id –

+0

¿Alguien puede ayudarme a entender por qué sucede esto, así puedo entender mejor a Ruby? –

Respuesta

6

Son todos el mismo objeto:

ree-1.8.7-2012.02 :001 > output = Array.new(5, []) 
=> [[], [], [], [], []] 
ree-1.8.7-2012.02 :002 > output[0] 
=> [] 
ree-1.8.7-2012.02 :003 > output[0].object_id 
=> 2219989240 
ree-1.8.7-2012.02 :004 > output[1].object_id 
=> 2219989240 
ree-1.8.7-2012.02 :005 > output[2].object_id 
=> 2219989240 
ree-1.8.7-2012.02 :006 > output[3].object_id 
=> 2219989240 
ree-1.8.7-2012.02 :007 > output[4].object_id 
=> 2219989240 
ree-1.8.7-2012.02 :008 > 

Prueba esto:

ree-1.8.7-2012.02 :008 > output = [] 
=> [] 
ree-1.8.7-2012.02 :009 > 5.times{output << []} 
=> 5 
+0

Gracias Pedro! Lo siento, me tomó tanto tiempo marcar tu respuesta. –

5

Todos ellos tienen el mismo identificador de objeto, como se ha señalado por Pedro Nascimento, si las matrices se inicializan de esa manera. Usted puede evitar esto mediante el uso de un similar syntax para crear sus matrices anidadas:

irb(main):047:0> output = Array.new(5) {[]} 
=> [[], [], [], [], []] 
irb(main):048:0> output.each {|i| puts i.object_id} 
10941700 
10941680 
10941660 
10941640 
10941620 

Así que su anexados para output[0] funcionará como se espera:

irb(main):049:0> output[0] << "cat" 
=> ["cat"] 
irb(main):050:0> output 
=> [["cat"], [], [], [], []] 
1

El código

output = Array.new(5, []) 

está tratando para crear una sola copia del objeto,

Así

ree-1.8.7-2012.02 :003 > output[0].object_id 
=> 2219989240 
ree-1.8.7-2012.02 :004 > output[1].object_id 
=> 2219989240 
ree-1.8.7-2012.02 :005 > output[2].object_id 
=> 2219989240 
ree-1.8.7-2012.02 :006 > output[3].object_id 
=> 2219989240 
ree-1.8.7-2012.02 :007 > output[4].object_id 
=> 2219989240 

Si desea crear varias copias del objeto, utilice este

 output = Array.new(5) {[]} #=> [[], [], [], [], []] 

El código

output.each {|i| puts i.object_id} 

le mostrará

1.9.3-p194 :005 > output.each {|i| puts i.object_id} 
13417360 
13417340 
13417320 
13417300 
13417280 
=> [[], [], [], [], []] 
Cuestiones relacionadas