Question

I am facing something i do not fully understand.

I have an array whose elements are arrays.

So I have two nested loops, in the inner loop I fill my inner array then in the outer loop i fill the outer array with the inner array.

arr=[]
mat=[]
for m in (0..1)
  for k in (0..1)
    arr[k]=rand.to_s
  end
  mat[m]=arr
end

At the end my matrix is filled with two array; each array contains the values calculated in the last iteration. If i want the first element in matrix to contain the first computed array I have to reinitialize the arr object at each loop. So it seems that assignment is made by reference until the arr object is "cleaned". If I add

mat[m]=arr
arr=[]

all works as expected: mat[0] will contain the array computed in the first loop, and mat[1] will contain the array computed in the second loop.

Is this by design or is it an undesired side effect? This is happening only if I assign arrays as array elements. If if fill an array with simple string variables in a loop all goes as expected.

I know that it is good programming practice to avoid reusing objects, but this behavior is anyway strange.

Was it helpful?

Solution

Your problem is that your arr variable's contents is being overwritten with each iteration: the arr[k] overwrites whatever is in there already. The arr variable needs to be local to the block instead:

mat = []
2.times do             # avoid for... use iterators instead
  row = []
  2.times do 
    row << rand.to_s
  end
  mat << row
end

OTHER TIPS

I like the approach of using hashes instead of multidimensional arrays.

How about this:

def creat­e_matrix x, y, conte­nt = nil, &block
  rows = (0...x­).to_a
  cols = (0...y­).to_a
  indices = rows.­product cols
  matrix = {}
  indices.ea­ch { |inde­x| matri­x[index] = ( block­_given? ? yield­( index ) : conte­nt ) }
  matrix
end

Then do:

matrix = create_matrix( 2, 2 ) { rand.to_s }

You will get a hash, that you can access like this:

matrix[[0, 1]] #note the double brackets

Another way of doing it:

(1..4).map{rand}.each_slice(2).to_a
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top