Ordinal -> Enum Value

Started by _PJ_, December 30, 2024, 13:34:57

Previous topic - Next topic

_PJ_

Is there a more efficieent or direct way to "retrieve" the Enum value from an integer assigned to its ordinal?

To clarify as my description is terrible  - If I want to know the correspondign Enum from an integer, I currently iterate through each Enum field until I match the corresponfing one: 

Enum Enumerals
E_1=1
E_2
E_3
End Enum

Local TestInt:Int = 2

For Local EIterate:Enumerals=EachIn Enumerals.Values()
If EIterate.Ordinal()=TestInt Then Print "Value found: "+EIterate.Ordinal()
Next
[/quote]

I am wondering if there is a method that essentially performs the invesrese of MyEnum.Ordinal() 
Such as 

MyEnum:Value(Ordinal:Int)

If that makes sense?

Derron

While "behind the scenes" enums default to integers they can also be defined to be bytes etc.

Nonetheless they are a kind of "type" ... and now you want to compare "1" with "something". If you had a type "TCar" (which had a field "id:int") and asked to retrieve the car instance by a number (so id = number) then this also requires some "go through all instances until you find the right car instance" (and then you speed it up by using an TintMap or an integer array + offsets...).

Similar is what I would propose here: if you often need to check a numeric value versus an enum, you might consider storing the enums in an array, give it an offset (so first array index is the default enum ...so "Enumerals.none" would fit well there). Then you can always use your lookup table "enum_lut[mynumber]" to retrieve the enum ... but check boundaries first..

This would look like this:
SuperStrict
Framework Brl.StandardIO
Import Brl.Retro


Enum ETest
None = 0
E1 = 1
E2
E3
End Enum


Local lutInt2EnumE:ETest[] = New ETest[ ETest.Values().Length ]
Local i:Int
For Local e:ETest = EachIn ETest.Values()
lutInt2EnumE[i] = e
i :+ 1
Next


Print lutInt2EnumE[1].ToString()
Print lutInt2EnumE[3].ToString()


But but but ... before copying this ... is all of this really needed? What is this "values()" thing ?
https://blitzmax.org/docs/en/language/enums/

QuoteThe 
Values() function returns an array of all elements:

So ... this is already our lookup table which allows to access the enums by their index...


SuperStrict
Framework Brl.StandardIO
Import Brl.Retro


Enum ETest
None = 0
E1 = 1
E2
E3
End Enum


Print ETest.Values()[1].ToString()
Print ETest.Values()[3].ToString()


Of course this is an access "by index", not "by value". So if the values of the enum would be arbritrary, or "bitmask/flags" you need to create a lookup table - and if values can become very big (talking about value bigger than 1000) you might better use a TIntMap for your lookup "table" then. For smaller stuff I would simply still use a "arr:ETest[]" with all the unused ones resulting in the "none"-enum.


This could look like this:
SuperStrict
Framework Brl.StandardIO
Import Brl.Retro


Enum ETest
None = 0
E1 = 10
E2 = 30
E3 = 50
End Enum

'find max
Local eMax:Int
For Local e:ETest = EachIn ETest.Values()
eMax = Max(0, e.Ordinal())
Next
Print "Max: " +eMax


Local lutInt2EnumE:ETest[] = New ETest[ eMax + 1 ]
'fill empty with default
For Local i:Int = 0 Until lutInt2EnumE.Length
lutInt2EnumE[i] = ETest.None
Next
'fill existing enums
For Local e:ETest = EachIn ETest.Values()
lutInt2EnumE[ e.Ordinal() ] = e
Next


Print lutInt2EnumE
.ToString()
Print lutInt2EnumE[5].ToString()
Print lutInt2EnumE[10].ToString()
Print lutInt2EnumE[43].ToString()


bye
Ron

_PJ_

Hi Ron,
Thanks so much for your extremely detailed response. So it is necessary to iterate through  to find the match.

The reason I was asking was because I have some data that is saved to disk and loaaded back in - To write the "Enum" values to disk, I am writing them as Ordinals (Integers) so when it is time to load them back in again, I need to lookup each one.

It sounds so obvious now in hindsight, but I think a lookup table (or array - it's only 1 dimensional) would be enough - and, as you mention, the fact that this is literally what EachIn Values() already provides, and I only have around 20 or so different value combinations!