Page 1 of 2
Get mapKey() of single map element?
Posted: Fri Jul 19, 2019 8:08 pm
by doctorized
In help, MapKey() is used like this:
Code: Select all
NewMap Country.s()
Country("US") = "United States"
Country("FR") = "France"
Country("GE") = "Germany"
ForEach Country()
Debug MapKey(Country())
Next
With this way it goes through all elements of the map and shows the key. What should we do if we want to get the key for a specific element, for example "France"?
Re: Get mapKey() of single map element?
Posted: Fri Jul 19, 2019 8:15 pm
by infratec
Code: Select all
NewMap Country.s()
Country("US") = "United States"
Country("FR") = "France"
Country("GE") = "Germany"
Country("FR")
Debug MapKey(Country())
MapKey() returns the key of the current selected element.
So you have to select it.
But then you know already the key.
Or:
Code: Select all
NewMap Country.s()
Country("US") = "United States"
Country("FR") = "France"
Country("GE") = "Germany"
ForEach Country()
If Country() = "France"
Debug MapKey(Country())
EndIf
Next
Or you need an additional 'reverse' Map:
Code: Select all
NewMap CountryByShort.s()
NewMap ShortByCountry.s()
CountryByShort("US") = "United States"
CountryByShort("FR") = "France"
CountryByShort("GE") = "Germany"
ForEach CountryByShort()
ShortByCountry(CountryByShort()) = MapKey(CountryByShort())
Next
Debug CountryByShort("FR")
Debug ShortByCountry("France")
Re: Get mapKey() of single map element?
Posted: Fri Jul 19, 2019 9:11 pm
by doctorized
infratec wrote:MapKey() returns the key of the current selected element.
So you have to select it.
But then you know already the key.
Hahahahahaha!!! If I know the key then what is my problem? Hahahaha!!!
infratec wrote:
Or:
Or you need an additional 'reverse' Map:
I knew that
Code: Select all
ForEach Country()
If Country() = "France"
Debug MapKey(Country())
EndIf
Next
does the job but I don't get it, why do we have to loop all elements to find the one we need? Shouldn't it work like
to give the element? Isn't it better?
Re: Get mapKey() of single map element?
Posted: Fri Jul 19, 2019 9:19 pm
by Josh
If you are looking for a reverse function to search for the value of a map entry, you will have no choice but to go through the map. How else could it be? The content of a map element can also be a structure.
Maybe, this can help you. For Maps there is no equivalent to the list command ChangeCurrentElement(). You can use the following workaround:
Code: Select all
CompilerIf Defined (ChangeCurrentMapElement, #PB_Function) = #False
Macro ChangeCurrentMapElement (MyMap, NewMapElement)
FindMapElement (MyMap, PeekS (PeekI (NewMapElement - SizeOf (Integer))))
EndMacro
CompilerEndIf
Re: Get mapKey() of single map element?
Posted: Fri Jul 19, 2019 9:36 pm
by doctorized
Josh wrote:If you are looking for a reverse function to search for the value of a map entry, you will have no choice but to go through the map. How else could it be? The content of a map element can also be a structure.
Maybe, this can help you. For Maps there is no equivalent to the list command ChangeCurrentElement(). You can use the following workaround:
Code: Select all
CompilerIf Defined (ChangeCurrentMapElement, #PB_Function) = #False
Macro ChangeCurrentMapElement (MyMap, NewMapElement)
FindMapElement (MyMap, PeekS (PeekI (NewMapElement - SizeOf (Integer))))
EndMacro
CompilerEndIf
There are a few complicated workarounds. I had a hope that MapKey() would be a little more useful/helpful and I did't have to search all elements myself. Anyway, it doesn't matter. Thank you both for you replays! I really appreciate them!
Re: Get mapKey() of single map element?
Posted: Fri Jul 19, 2019 9:54 pm
by NicTheQuick
In every programming language a map usually works only in one direction. If you want a map that works in both directions you have to create it by yourself, for example by using two normal maps.
Re: Get mapKey() of single map element?
Posted: Fri Jul 19, 2019 10:22 pm
by nco2k
doctorized wrote:I don't get it, why do we have to loop all elements to find the one we need?
the key is unique, the value is not. thats why.
doctorized wrote:I had a hope that MapKey() would be a little more useful/helpful
MapKey() does exactly what it should do, which is returning the key. if you want to get a specific value, you have to search for it, or create two maps and cross reference them.
you are using maps wrong however. the key is something that you know, and the value is something that you dont know, but want to access quickly.
c ya,
nco2k
Re: Get mapKey() of single map element?
Posted: Sat Jul 20, 2019 12:04 am
by doctorized
nco2k wrote:the key is unique, the value is not. thats why.
In my case, values are unique as the are coming from enumeration.
nco2k wrote:you are using maps wrong however. the key is something that you know, and the value is something that you dont know, but want to access quickly.
I want a connection between strings and numbers coming from enumeration. The numbers are stored in a database (I use the numbers for smaller db). Strings are used to represent the numbers in a list icon gadget. So, I need both direction connectivity. The string gives a number to be stored, the number read is used to get the string to show. Any suggestion other than the map? With the foreach loop I am ok right now. Anything else better than this?
Re: Get mapKey() of single map element?
Posted: Sat Jul 20, 2019 6:31 am
by the.weavster
Code: Select all
UseSQLiteDatabase()
db = OpenDatabase(#PB_Any,":memory:","","",#PB_Database_SQLite)
; etc...
Re: Get mapKey() of single map element?
Posted: Sat Jul 20, 2019 7:44 am
by Josh
Uh-huh. You have a database, you have a map and you have the values from an enumeration. Seems a bit weird, hard to keep track of and hard to maintain. You should rethink your system from scratch.
I have no idea about the possibilities in PureBasic databases. But normally I would store the texts in an own table in the database.
doctorized wrote:I want a connection between strings and numbers coming from enumeration. The numbers are stored in a database (I use the numbers for smaller db). Strings are used to represent the numbers in a list icon gadget. So, I need both direction connectivity.
If you don't want to build it as a pure database solution, then I would write the strings into a map and save the pointer to the map entry in the database. How you get the Mapkey from the pointer I already described above. This way you save the whole spell with values, enumeration, search, etc.
Re: Get mapKey() of single map element?
Posted: Sat Jul 20, 2019 10:45 am
by nco2k
doctorized wrote:In my case, values are unique
it doesnt matter. the key has to be unique for the map to work properly. the value on the other hand is just a data container. the map doesnt care what you do with it. some other languages may offer what you want, but they still have to search for the item under the hood. so you arent gaining anything.
like i said, you could create two maps and cross reference them. but if the values are coming from enumerations, then i would use an array and a map instead. it really depends on what you are trying to do. you may not even need a map. you may not even need an array, as you could probably do everything within the ListIconGadget itself. the item position could be your "value", and the item text could be your "key". i assume that you want to interact with the ListIconGadget, so when you click an item, you already know the "value", and therefor can get the "key" easily. there are so many ways to tackle your issue. i would suggest that you go back to the drawing board and rethink your whole approach.
c ya,
nco2k
Re: Get mapKey() of single map element?
Posted: Sat Jul 20, 2019 1:32 pm
by kenmo
Just for reference, PB's "Map" and most language's "maps" or "dicts" or "associate arrays" are one-directional, and multiple keys can have the same value.
Think Object("height") = 5 and Object("width") = 5
https://en.wikipedia.org/wiki/Associative_array
Doctorized's case is a one-to-one mapping with no duplicates, so it could use a "bidirectional map" or "bimap" or "bidict" but I don't think most languages natively implement these.
The solutions above in this thread work.
https://en.wikipedia.org/wiki/Bidirectional_map
Re: Get mapKey() of single map element?
Posted: Sat Jul 20, 2019 7:15 pm
by Demivec
doctorized wrote:nco2k wrote:the key is unique, the value is not. thats why.
In my case, values are unique as the are coming from enumeration.
nco2k wrote:you are using maps wrong however. the key is something that you know, and the value is something that you dont know, but want to access quickly.
I want a connection between strings and numbers coming from enumeration. The numbers are stored in a database (I use the numbers for smaller db). Strings are used to represent the numbers in a list icon gadget. So, I need both direction connectivity. The string gives a number to be stored, the number read is used to get the string to show. Any suggestion other than the map? With the foreach loop I am ok right now. Anything else better than this?
If both the key and the value are unique with respect to themselves and to each other you can store them in the same map.
Re: Get mapKey() of single map element?
Posted: Sat Jul 20, 2019 8:24 pm
by skywalk
Most of my apps use a disk based database(permanence) and a mirrored memory database for interim query speed. For internal gui updates,number crunching, or other stuff I choose from the following rules:
Code: Select all
; DEF: When to use array|list|map?
; Map: Unique list, no order. Text defines elements.
; Ex. Menu items, except watch for sub-menus with same names.
; MapSize(map()) returns base 1 count.
; List: Ordered list. Usually small and unknown size at creation.
; Ex. Retrieving a table's contents without knowing count.
; Or appending to existing list without care to size.
; ListSize(ll()) returns base 1 count.
; Array: When speed or list size demand.
; ArraySize(ar()) returns base 0 count.
Re: Get mapKey() of single map element?
Posted: Sat Jul 20, 2019 8:31 pm
by nco2k
Demivec wrote:If both the key and the value are unique with respect to themselves and to each other you can store them in the same map.
which could introduce potential problems in the future, if your rules ever change. its better to keep them separate, and reference them through pointers.
c ya,
nco2k