2 votes

Tenter de changer la valeur d'un tableau à 2 dimensions en ruby change toutes les valeurs, et je ne connais pas de solution de contournement.

J'essaie de créer quelque chose qui nécessite un tableau à deux dimensions afin de choisir ce qui doit être affiché à l'écran, mais j'ai remarqué une certaine bizarrerie et je ne sais pas comment la contourner. Création d'un tableau 2d via Array.new fait que toute tentative de définir une valeur dans un tableau imbriqué la définit dans tous les tableaux imbriqués.

a = Array.new(3, Array.new(3, 0)) #=> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
a[1][1] = 1                       #=> 1
a                                 #=> [[0, 1, 0], [0, 1, 0], [0, 1, 0]]

Cependant, créer le même tableau en spécifiant chaque valeur n'a pas le même comportement (et c'est ainsi que je m'attendais à ce que cela fonctionne).

b = [[0,0,0],[0,0,0],[0,0,0]]     #=> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
b[1][1] = 1                       #=> 1
b                                 #=> [[0, 0, 0], [0, 1, 0], [0, 0, 0]]

Je ne sais pas exactement pourquoi cela se produit, et je n'arrive pas à trouver une meilleure façon de créer ce tableau, car spécifier chaque valeur individuelle prendrait une éternité. Pourquoi cela se produit-il, et comment puis-je l'éviter à l'avenir ?

0voto

Chris Dutton Points 255

Vous avez créé un tableau contenant trois références au même objet. Ainsi, lorsque vous en modifiez une, vous les modifiez toutes, car elles sont toutes identiques.

Nous pouvons le constater avec #object_id .

Array.new(3, Array.new(3, 0)).map(&:object_id)
# => [70368430794940, 70368430794940, 70368430794940]

En utilisant la forme de bloc de Array#new résoudra ce problème.

Array.new(3) { Array.new(3, 0) }.map(&:object_id)
# => [70368431982020, 70368431982000, 70368431981980]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X