Trouble iterating through a dictionary where the values are identical for multiple keys.

Godot Version

4.7.2

Code

	print("turn order: " + str(turnorder))
	for key in turnorder:
		print("for key in turnorder")
		var value = turnorder[key]
		print("value: " + str(value))
		print("highroll: " + str(highroll))
		if value == highroll:
			print("if value == highroll")
			currentunits.append(key)
			turnorder.erase(key)

Output

turn order: { Unit:<AnimatedSprite2D#39325795935>: 0, Unit2:<AnimatedSprite2D#39342573152>: 0 }
for key in turnorder
value: 0
highroll: 0
if value == highroll
current units: [Unit:<AnimatedSprite2D#39325795935>]

Question

When it comes to dictionaries, I’ve noticed there are problems with iterating through them if the values in key value pairs are identical. It will only iterate through the first value in that case, which is tricky because I need both. The output shows the evidence of this.

My goal here is to create a turn order system that puts both units into the current units dictionary if they roll equally. Is there any way of properly iterating through the dictionary without it dropping iterations when they share the same value?

Your issue comes from a fact that you’re erasing the elements while iterating through the Dictionary, which is not supported.

Note: Erasing elements while iterating over dictionaries is not supported and will result in unpredictable behavior.

Yeah, and this can easily be resolved by changing the line

for key in turnorder:

into

for key in turnorder.keys():

Because, as far as I’m aware, .keys() creates a copy of the dictionary’s keys as array.

Thank you both for the answers! I managed to find a workaround before they came through, but I understand now what was happening. The dictionary iteration of the keys erases the key-value pair of the one of the same value before it gets to looping through it, preventing both values from being erased. I managed to solve it with a while loop since I only needed the values matching highroll to be replaced.

	for key in turnorder:
		print("for key in turnorder")
		var value = turnorder[key]
		print("value: " + str(value))
		print("highroll: " + str(highroll))
		if value == highroll:
			print("if value == highroll")
			currentunits.append(key)
	while turnorder.values().has(highroll):
		turnorder.erase(turnorder.find_key(highroll))