get the index in a for each loop

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

Hi dear community.

I’m trying to iterate a foreach loop using a for in like in the next example. I need to get the index to multiply the button size and spawn it in the correct spot.

func create_buttons():
	for i, unit in selected_units: //i gives me an error
		if not buttons.has(
			var but =  button.instance()
			var offset = 64
			but.rect_position = Vector2(buttons.size() * i + offset , $UI/NinePatchRect.rect_size / 2)

I know i can create an var outside the loop and the incrementate but thats ugly.

I’m new in gdscript and python. Any kind of help will be appreciated.

:bust_in_silhouette: Reply From: kidscancode

Presumably selected_units is an array.

In Python, you could use enumerate to get the functionality you’re looking for.

for i, unit in enumerate(selected_units):

Iterating arrays in GDScript is not as full-featured as Python. If you want to have the index and item, you need to iterate through indices:

for i in range(selected_units.size()):
    if not buttons.has(selected_units[i].name):
    # etc

For loop can be written shortly iterating all elements:

for i in selected_units.size():

Xrayez | 2018-11-27 19:21

True, but I tend to default to the range() construction as more explicit (and out of Python habits).

kidscancode | 2018-11-27 19:25

:bust_in_silhouette: Reply From: Zylann

You can do it like this too:

for i in len(selected_units):
    var unit = selected_units[i]

I tend to not use range in for loops because although it looks nicer in the Python sense, Godot does not have iterables, which means range returns an array, so if your list is huge it will create an array of that size everytime (impact is negligible for small lists).

Edit: actually this was true in Godot 2 but an exception for for loops might have changed in Godot 3, I’m not exactly sure right now