Filling two array of array

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Andrea

Hello,
I just found out that, if I create 2 matrix using this method:

var cell_code=[]
var cell_type=[]

func create_matrix(row,column):
	for x in range(column):
		var col=[]
		col.resize(row)
		cell_code.append(col)
		cell_type.append(col)
    cell_code[1][1]="hello"
    print(cell_type[1][1])

the two variable cell_code and cell_type will be forever linked in a magical way.
As a matter of fact, the above function will print "hello".

Is this a wanted behavior? How can I overcome it? Is there a better way to create matrix?

:bust_in_silhouette: Reply From: SIsilicon

The behaviour must be because you are appending the same array to both of the arrays.
Try appending a different array for cell_code and cell_type separately.

Appending the same array is indeed the reason of the problem, and doing as you say solves the issue.
However, since i want to have many matrix (one for each property of the cell), it is quite uncomfortable to have so many col variables, one for each matrix.
So, do you know an easier way to create many matrix?

PS: just for the sake of knowledge, I would like to know what is happening in the code i wrote previously, why is it behaving like that?
It seems like, while writing cell_code[1][comment0-1]="hello" I am actually writing inside col[1], and this would explain why cell_type get modified too.
However if that´s the reason, remember that every row of the matrix is a copy of col, meaning that cell_code[1][comment0-2] and cell_code[1][comment0-3] and cell_type[1][comment0-2] and cell_type[1][comment0-3] should be overwritten as well, but that´s not the case.

I´m really puzzled!

Andrea | 2018-04-10 20:03

It because an assignment to a non primitive type usually means it holds a reference to that object/array instead of copying the value. The behavior is the same with other languages, with a few exceptions like c++ (you can still achieve this in c++ by using pointers)

var a = []; (means "a" hold a reference to the array)
var b = a; (means "b" hold reference to the array a is pointing to)
b.append(1) means that the array that they both reference is now [1]

contrast this with

var a = 1;
var b = a; (the value of a is copied to b)
print(b+1) //will be 2
print(a) //will be 1

alether | 2018-04-11 04:44

Thank you very much! Understood, it´s an important thing to know while working with arrays.
The only question remaining is if there is a better way to create a matrix without encountering this issue: do matrix exist on gdscript or they are only a sequence of mono-dimensional arrays (impossible to separate from the arrays they originate from)?

Andrea | 2018-04-11 11:41

I just finished reading back in the docs and I got to an interesting part.
Apparently, dictionaries can be used to create a matrix, and are possibly more efficient to use and sample from.
Eg:

var mat = {}
mat[Vector2(1, 2)] = 1.0 #sets the third element in the second column to 1.
var s = mat[Vector2(3, 0)] #retrieves the first element in the fourth column; which would be null by default.

SIsilicon | 2018-04-12 01:11

I tried it in my project and it works flawlessly!!
That´s exactly the kind of easy matrix management i was looking for, thanks you sooo much!!

Andrea | 2018-04-12 08:41