Get mapKey() of single map element?

Just starting out? Need help? Post your questions and find answers here.
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Get mapKey() of single map element?

Post 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"?
infratec
Always Here
Always Here
Posts: 7779
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get mapKey() of single map element?

Post 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. :wink:

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")
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Get mapKey() of single map element?

Post 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. :wink:
Hahahahahaha!!! If I know the key then what is my problem? Hahahaha!!!
infratec wrote: Or:

Code: Select all

...
Or you need an additional 'reverse' Map:

Code: Select all

...
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

Code: Select all

MapKey("France")
to give the element? Isn't it better?
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: Get mapKey() of single map element?

Post 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
sorry for my bad english
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Get mapKey() of single map element?

Post 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!
User avatar
NicTheQuick
Addict
Addict
Posts: 1561
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Get mapKey() of single map element?

Post 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.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: Get mapKey() of single map element?

Post 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
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Get mapKey() of single map element?

Post 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?
User avatar
the.weavster
Addict
Addict
Posts: 1582
Joined: Thu Jul 03, 2003 6:53 pm
Location: England

Re: Get mapKey() of single map element?

Post by the.weavster »

Code: Select all

UseSQLiteDatabase()
db = OpenDatabase(#PB_Any,":memory:","","",#PB_Database_SQLite)
; etc...
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: Get mapKey() of single map element?

Post 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.
sorry for my bad english
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: Get mapKey() of single map element?

Post 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
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
User avatar
kenmo
Addict
Addict
Posts: 2078
Joined: Tue Dec 23, 2003 3:54 am

Re: Get mapKey() of single map element?

Post 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
User avatar
Demivec
Addict
Addict
Posts: 4283
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Get mapKey() of single map element?

Post 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.
User avatar
skywalk
Addict
Addict
Posts: 4298
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Get mapKey() of single map element?

Post 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.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: Get mapKey() of single map element?

Post 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
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
Post Reply