How do I create a 2D array ?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By sandheaver
:warning: Old Version Published before Godot 3 was released.

I can create a 1-dimensional array as follows:

var list = []

How would I create a 2-dimensional array? I can’t seem to find an obvious example in the docs or project examples. In Python I think it would be:

var matrix = [[0 for x in range(width)] for y in range(height)] 

but this returns an error in Godot.

:bust_in_silhouette: Reply From: Gokudomatic2

godotscript is not python and doesn’t follow the pythonic way. Simply do it the old fashion way:

var matrix=[]
for x in range(width):
    matrix[x]=[]
    for y in range(height):
        matrix[x][y]=0

This approach is returning an error " Invalid set index ‘0’ (on base: ‘Array’). " at the first step

matrix[x] = []

sandheaver | 2016-06-11 07:32

Strange. I did try it yesterday. Anyway, maybe using

matrix.append([])

does the trick. The theory for the n dimensional matrix doesn’t change.

Gokudomatic2 | 2016-06-11 08:03

Thank you , that seems to fix the problem:

var matrix = []
for x in range(width):
	matrix.append([])
	matrix[x]=[]		
	for y in range(height):
		matrix[x].append([])
		matrix[x][y]=0

sandheaver | 2016-06-11 08:31

Almost, I fixed it for you. Your method had some redundancies that slowed it down.

var matrix = []
for x in range(width):
    matrix.append([])
    for y in range(height):
        matrix[x].append(0)

#matrix=
this sets the you just appended into a
#matrix.append()
#matrix[comment3-y]=0
these append a and then set the to a 0, which is weird and inefficient

the cleaned up method simply starts with a , then adds as rows, ex: [ ,, ]
then adds 0’s into the rows, ex: [ [0,0,0],[0,0,0],[0,0,0] ]

one last side note: if you are making a very large 2D array (300x300 or higher), it seems to be faster to use a while loop instead of the for each loop with the range method, because the range method does something along the lines of building an array, ex: range(3) makes an array = [0,1,2]. This is slower than simply having an increment counter, ex: int x = 0, while(x<3), x += 1

batmanasb | 2016-06-14 10:35

very helpful, thanks for the advice and improvements!

sandheaver | 2016-06-15 19:12

Use append_array() for arrays, efficient for it expects specifically an array.
Examples:

array1.append_array(array2)

Psyboyo | 2022-08-11 17:54

:bust_in_silhouette: Reply From: vitalfadeev

Or such:

func create_map(w, h):
	var map = []
	
	for x in range(w):
		var col = []
		col.resize(h)
		map.append(col)

	return map

Return Null-filled array.

:bust_in_silhouette: Reply From: atme

This is the way I create 2d arrays in godot:

var array_a = [1,2,3,4]
var array_b = [5,6,7,8]

var array_2d = [array_a, array_b]

And then, to read:

array_2d[0,1] -> 2
array_2d[1,2] -> 7

I believe the correct way to read/write is (now):

array_2d[0][1] -> 2 

etc…

At least that’s what i experienced in Godot 3.0

Constantin | 2018-02-14 23:18

:bust_in_silhouette: Reply From: mateusak

Seeing these awful answers; this is the most performance-friendly way of creating it:

func create_2d_array(width, height, value):
	var a = []

	for y in range(height):
		a.append([])
		a[y].resize(width)

		for x in range(width):
			a[y][x] = value
			
	return a

To be used as array[y][x].

This comment is ancient now, but why did you put y before x? That seems pretty programmer-unfriendly, considering that every other time coordinates are used, they go in alphabetical order (x,y)

Davi-Danger | 2019-05-14 15:57

@Davi-Danger, that isn’t always true. It comes down to row-major vs. column major, which very much depends on the application of the 2D array. If I’m modeling something like a matrix, it isn’t uncommon at all to have y first; and in some APIs it’s the standard to do it that way.

After all, it doesn’t just affect how the programmer sees it, it affects how it’s arranged in memory.

vikinghelmet99 | 2019-06-18 18:38

2D Arrays are still not listed in documentation.

cloa513 | 2021-10-25 14:54

:bust_in_silhouette: Reply From: Galm_1
#creating 2D Arrays in GDscript
var my_array = [[]]

var width = 5
var height = 5

func _ready():
#setting 2D Array size
for x in width:
	my_array.resize(width)

	for y in height:
		my_array[x].resize(y)
      
#setting a value
my_array[0][0] = 1

Isn’t it that the function _ready() should be replaced with _init() because the following code is initialization rather than something to do after entering the tree?

ChrisDoufu | 2022-09-21 00:29

:bust_in_silhouette: Reply From: OaktownStudios

The simplest way is probably:

var r = [0,0,0,0,0,0,0,0,0,0,0,0,0]#r for row
var matrix = [r,r,r,r,r,r,r,r,r,r,r,r,r,r,r]

Unfortunately your answer will lead to a serious problem if you change any one of the elements in matrix. Say you assign matrix[0][comment0-0] = 1, then matrix will become something like

[
    1, 0,0,0,0,0,0,0,0,0,0,0,0
    1, 0,0,0,0,0,0,0,0,0,0,0,0
    ...
    1, 0,0,0,0,0,0,0,0,0,0,0,0
]

Since you have repeated appended the same r to matrix, the underlying elements in matrix is referencing the same memory block, i.e., matrix[0] and matrix[1] is pointing to the same memory block which is also referenced by var r.

This is because r is shallowly copied into matrix. You should use deep copy instead.

ChrisDoufu | 2022-09-21 00:29

:bust_in_silhouette: Reply From: ffaemiyi

extends Node2D
var Ail_List = Array()
func _on_Button_pressed():
$Label.text=str(“hi”)
Ail_List = make_2d_array()
print(Ail_List)
print(Ail_List[0][3])

func make_2d_array():
var array_1 = Array()
var i_hei =[0,1 ,2 ,3 ,4, 5, 6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15 ,16]
var width = 4
var height = 4
var coun_ok = 0
for i in width:
var array_2 = Array()
for j in height:
array_2.append(i_hei[coun_ok])
coun_ok += 1
array_1.append(array_2)
return array_1

:bust_in_silhouette: Reply From: MohammedUnicold
                X1      X2
var Arr2D = [[y1,y2],[y1,y2]]

you dont need a code to do it , its just that easy!!!

look here is an Example :

var Arr2D = [[1,3],[2,4]]
print(Arr2D[0][1])

will print 3

:bust_in_silhouette: Reply From: Winters

I get that a lot of these are joke answers because the real answer is really simple, but in case someone actually doesn’t know.

var matrix = [[],[]]

append as needed