I have the following code
visited = [[false]*4] * 3
which shows me the 2-D array
[[false, false, false, false], [false, false, false, false], [false, false, false, false]]
now I wish to change the element at row 1, column 2 as shown:
[[false, false, false, false], [false, false, false, false], [false, false, false, false]]
^
so I did the following:
visited[1][2] = 1
but now when I inspect the 2-D array, I get the following output:
puts visited.inspect
> [[false, false, 1, false], [false, false, 1, false], [false, false, 1, false]]
I can't seem to figure out why all the rows at the same column index get populated by 1?
Edit:
I tried initializing my array visited
by typing out all the elements manually (without multiplying the arrays) and it worked fine. I wonder why this is the case? Apologies if this is not the proper convention for doing so, I come from a Python background.
CodePudding user response:
You have three references to the same array. A change in one is a change in all three because there aren't really three at all.
This can be seen by using #object_id
.
irb(main):005:0> visited = [[false]*4] * 3
=> [[false, false, false, false], [false, false, false, false], [false, false, false, false]]
irb(main):006:0> visited.map(&:object_id)
=> [70221746802920, 70221746802920, 70221746802920]
Now consider:
irb(main):008:0> visited = 3.times.map { [false] * 4 }
=> [[false, false, false, false], [false, false, false, false], [false, false, false, false]]
irb(main):009:0> visited.map(&:object_id)
=> [70221746635240, 70221746635200, 70221746635160]
All three arrays have unique object IDs.
irb(main):010:0> visited[0][2] = 42
=> 42
irb(main):011:0> visited
=> [[false, false, 42, false], [false, false, false, false], [false, false, false, false]]
CodePudding user response:
This is because in Ruby everything is an object, and Ruby defaults to passing a reference to that object. So your 2D array consists of three references to the same four member array. What you do to one, you do to all three.