Iterate over enum in return enum names, not values

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

I was trying to iterate over an enum, to check if a certain condition matches for each entry of a dictionary with enum values as keys, i.e. :

enum StrikeType {
    PUNCH,
    KICK,
    KNOCK
}

# ...
func _is_hitting_started():
    for strike_type in StrikeType:
        if _is_striking_climax(strike_type):
            return true

    return false

func _is_striking(strike_type):
    return sprite.animation == animations_per_strike_type[strike_type]

Inside for loop, I expected to have in strike_type values like 0, 1 and 2 (as enums are supposed to be a sort of alias of constants in GDScript). But instead, literals are returned (PUNCH, KNOCK and KICK)

A simpler way to understand this issue:

print("STRIKE TYPE DIRECTLY FROM ENUM: ", StrikeType.PUNCH)

This is printing 0

print("STRIKE TYPE DIRECTLY FROM ENUM: ", strike_type_from_for_loop)

This is printing PUNCH

Is there a way to solve this, or should I open a defect in Godot Github?

Thanks in advance.

I also think this is very odd behaviour for an enum. So I could certainly see it as being a bug.

My understanding of the why, is that it comes down to the way enums largely seem to be treated as key / value pairs. If you set out to create key/value pairs, it would make sense to iterate over the keys by default instead of the values. I suppose that enums were painted with the same brush.

That enums aren’t fundamentally supposed to be key/value pairs in that way is, I suppose, another matter entirely.

GameCarpenter | 2022-10-19 17:21

:bust_in_silhouette: Reply From: Lucas Coelho

The answer is almost in your question. The same way you can get the ‘ID’ doing StrikeType.PUNCH, and for are going to return PUNCH (the same with KICK and KNOCK), you can do StrikeType[strike] (as you call strike into the for loop). As you can’t do something like StrikeType.strike, you did it inside the brackets.

:bust_in_silhouette: Reply From: DogeMassaji

You could useDictionary.values().For example,

for value in dict.values():
    #do something