[]= and two dimensional arrays


#1

I expect:
irb(main):002:0> a = Array.new.fill(Array.new.fill(“x”, 0, 4), 0, 4)
=> [[“x”, “x”, “x”, “x”], [“x”, “x”, “x”, “x”], [“x”, “x”, “x”, “x”],
[“x”,
“x”, “x”, “x”]]
irb(main):003:0> p a
[[“x”, “x”, “x”, “x”], [“x”, “x”, “x”, “x”], [“x”, “x”, “x”, “x”], [“x”,
“x”, “x”, “x”]]
=> nil
irb(main):004:0> a[2][3] = “a”
=> “a”
irb(main):005:0> p a
[[“x”, “x”, “x”, “a”], [“x”, “x”, “x”, “a”], [“x”, “x”, “x”, “a”], [“x”,
“x”, “x”, “a”]]
=> nil
irb(main):006:0>

========================

I get:
irb(main):002:0> a = Array.new.fill(Array.new.fill(“x”, 0, 4), 0, 4)
=> [[“x”, “x”, “x”, “x”], [“x”, “x”, “x”, “x”], [“x”, “x”, “x”, “x”],
[“x”,
“x”,
“x”, “x”]]
irb(main):003:0> p a
[[“x”, “x”, “x”, “x”], [“x”, “x”, “x”, “x”], [“x”, “x”, “x”, “x”], [“x”,
“x”, "x
", “x”]]
=> nil
irb(main):004:0> a[2][3] = “a”
=> “a”
irb(main):005:0> p a
[[“x”, “x”, “x”, “a”], [“x”, “x”, “x”, “a”], [“x”, “x”, “x”, “a”], [“x”,
“x”, "x
", “a”]]
=> nil

=========================

I spend hours debugging and when I find it out, I have no clue how to
solve
it.

Could somebody clue me as to a solution?

Thanks,

SonOfLilit


#2

Oi, got that all wrong. Correct version:

I expect:

[[“x”, “x”, “x”, “x”], [“x”, “x”, “x”, “x”], [“x”, “x”, “x”, “x”], [“x”,
“x”, “x”]]
", “a”]]

SonOfLilit


#3

Oh, solved. Solution:
a = Array.new.fill(Array.new.fill(“x”, 0, 4).dup, 0, 4)

I was storing references to the same array.

Is there a better idiom for bulding 2d arrays and initializing them to a
constant value?


#4

Son SonOfLilit wrote:

irb(main):004:0> a[2][3] = “a”
irb(main):002:0> a = Array.new.fill(Array.new.fill(“x”, 0, 4), 0, 4)
irb(main):005:0> p a
Could somebody clue me as to a solution?
OK, here’s the clue. You only have two arrays. Scroll down for spoilers.

OK, here’s the key.

a = Array.new.fill(Array.new.fill(“x”, 0, 4), 0, 4)

  1. create an array (the inner “Array.new”)
  2. fill it with 4 "x"s
  3. create another array (the outer “Array.new”)
  4. fill it with 4 references to the first array

What you want is probably:

a = Array.new(4) { Array.new(4, “x”) }

or

a = Array.new(4) { Array.new(4) { “x” }}

That will create a new array for each of the four elements it
initializes the outer array with.

The second version will give you 16 strings instead of just 4.

Cheers,
Dave


#5

Thank you very much. Didn’t know I could do a = Array.new(4) {
Array.new(4)
{ “x” }} :slight_smile:

Nive to learn something new.

SonOfLilit