Need to pass "Array by value"

Godot Version

4

Question

`Hello, I would like the following code to pass empty arrays by value so the same array is not appended to:

var neighbors = []

func _ready() -> void:
     neighbors.resize(1000)
     neighbors.fill([])

func otherFunction() -> void
     neighbors[first].append(middleID)
     neighbors[second].append(middleID)
     neighbors[middleID].append(first)
     neighbors[middleID].append(second)

Does anybody have an alternative method/data structure to get the functionality I am seeking? All 1000 elements of the array fill with the same values no matter the index I choose.

`

Hi,

Use the duplicate to pass a copy of the array not the original

someFunctionName(Array.duplicate())

func someFunctionName(PassedArray: Array) -> void:
  PassedArray.append()

or, pass the array as a reference to the function and then duplicate it on arrival.

func functionName(PassedArray: Array) -> void:
  var arrayCopy: Array = PassedArray.Duplicate()

Kindly

Ryn

I am having troubling implementing a solution using duplicate. Could you describe a solution that essentially gives me a 2-dimensional array of a predefined size (say 1000) where all internal arrays are empty?

Can you show the code your trying with duplicate, if you passing an array of arrays you need to use .duplicate(true) to duplicate all the sub arrays.

On the other hand, if your just wanting a blank array at the destination why not just create a new array there, no need to pass anything…

Ryn

I will be appending more values to the subarrays elsewhere, which is why I am not creating a new array on the spot.

var neighbors = []

func _ready() -> void:
     neighbors.resize(1000)
     neighbors.fill([].duplicate(true))

func otherFunction() -> void
     neighbors[first].append(middleID)
     neighbors[second].append(middleID)
     neighbors[middleID].append(first)
     neighbors[middleID].append(second)

:joy:

There is no function in your shown code in this post or the first, that passes anything by value.
You are using a class level array variable and sizing it, filling it with empty arrays, and in other function you are appending values to it.

This line creates an array of 1000 elements each of which is null (1 empty array):
neighbors.resize(1000)
In this command you are filling the array with empty arrays (1000 individual arrays):
neighbors.fill([])
Is that what you actually want?

var neighbors = []

func _ready() -> void:
	neighbors.resize(1000)
	neighbors.fill([])
	otherFunction(neighbors.duplicate(true))


func otherFunction(arrayCopy: Array) -> void:
	print(arrayCopy) 

This works, you just need to add your code in the other function, also your 'first, second and middle ID’s will need to be created as variables to do anything. Not really sure why you’d want to pass and empty array of arrays, would seem easier to just create and array where you need it…

If you only want to fill it with a single value then .fill(0) will give you an array full of zero’s, though this would be the default behaviour anyway.

Ryn

I would like neighbors to be a 2-dimensional array initialized with empty subarrays so that I can append to them. The problem with

neighbors.fill([])

is that in my otherFunction(), [0], [1], [2], [3]… all append to the same array. In other words, I would like the subarray of index middleID to have size=2 and subarrays indices “first” and “second” to each have size=1

I initially tried .fill(0), but I cannot append to these.
“nonexistent function append to base ‘int’”

Okay, so if you want to have different sized arrays in each element I would use something like the following:

var neighbors: Array[PackedInt64Array] = []

func _ready() -> void:
	neighbors.resize(10)

	neighbors[9].append(23)
	neighbors[5].append(34)

	print(neighbors)

In this way each element of neighbours can have as many entries as you wish and they can be treated as individual array if you desire.

Ryn

1 Like

In that case these won’t work

func otherFunction() -> void
     neighbors[first].append(middleID)
     neighbors[second].append(middleID)
     neighbors[middleID].append(first)
     neighbors[middleID].append(second)

Lets say first = 0
nieghbors[0] is an array so when you do this:
neighbors[first].append(middleID)
you change the element in neighbors from an array to the value of middleID
If you do this:
neighbors[0][first].append(middleID)
then you would make the first element of the first array contained in neighbors the value of middleID

This confusion can be avoided by type-ing your variables:
var neighbors:Array[Array]
This should give you an error if you try to give the first dimension an element that is not an array.

It looks like you are creating an array of structured data. Each element is going to be a group of information that is going to be consistent.

array[0] = first name, second name, middle id1, middle id2
array[1] = first name, second name, middle id1, middle id2
array[2] = first name, second name, middle id1, middle id2
etc

This structured data is a good candidate for a class:

class_name FullName  
var fistName:String
var secondName:String
var middleID1:String
var middleID2:String
...
var neighbors:Array[FullName]
1 Like