Map access questions

Just starting out? Need help? Post your questions and find answers here.
dougmo52usr
User
User
Posts: 62
Joined: Mon Jul 18, 2016 6:43 pm

Map access questions

Post by dougmo52usr »

I see in the help, that I can pass a Map ByRef like Procedure DebugMap(Map ParameterMap.s()).

Suppose I rather need to pick a map within a function at runtime. The code below which obviously fails compile, gives an idea of what I want to accomplish. Is there a way to create a local variable and initialize it to a map reference?

Code: Select all

Enumeration MapID
  #MapOfStringsA = 1
  #MapOfStringsB
  #MapOfStringsC
EndEnumeration

Global NewMap MapOfStringsA.s()
Global NewMap MapOfStringsB.s()
Global NewMap MapOfStringsC.s()

Procedure GetMapRef(Map MapOfStrings.s())
  ProcedureReturn @MapOfStrings()
EndProcedure

Procedure InitMap(MapID)
  Protected *MapOfStrings, i=0
  Select MapId
    Case #MapOfStringsA
      *MapOfStrings = GetMapRef(MapOfStringsA())
    Case #MapOfStringsB
      *MapOfStrings = GetMapRef(MapOfStringsB())
    Case #MapOfStringsC
      *MapOfStrings = GetMapRef(MapOfStringsC())
  EndSelect
  ForEach *MapOfStrings
    i = i + 1
    AddMapElement(*MapOfStrings(),"Key"+Str(i)
    *MapOfStrings() = i
  Next
  ForEach *MapOfStrings()
    Debug MapKey(*MapOfStrings())
  Next
EndProcedure

Procedure main()
  InitMap(#MapOfStringsA)
EndProcedure

main()
infratec
Always Here
Always Here
Posts: 7583
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Map access questions

Post by infratec »

What you are doing is not possible.

*MapOfStrings is only a pointer to the current map element and not a map pointer.

And even if it would work ...

Code: Select all

 
 ForEach *MapOfStrings
    i = i + 1
    AddMapElement(*MapOfStrings(),"Key"+Str(i)
    *MapOfStrings() = i
  Next
Inside the loop you add an element, so the loop maybe endless
And you assign an integer to a string map.

And, I don't fully understand what you want.
Ok, you want to have access to different maps in one procedure.
But what you want to do inside of the for loop?
infratec
Always Here
Always Here
Posts: 7583
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Map access questions

Post by infratec »

Maybe something like this:

Code: Select all

EnableExplicit

Enumeration MapID
  #MapOfStringsA
  #MapOfStringsB
  #MapOfStringsC
EndEnumeration


Structure TestMap_Structure
  Map MapOfStrings.s()
EndStructure

Structure Test_Structure
  List MapList.TestMap_Structure()
EndStructure

Global Test.Test_Structure

Procedure GetMapRef(Map MapOfStrings.s())
  ProcedureReturn @MapOfStrings()
EndProcedure

Procedure InitMap(MapID)
  Protected *MapOfStrings, i.i
  
  SelectElement(Test\MapList(), MapId)
  
  For i = 0 To 2
    AddMapElement(Test\MapList()\MapOfStrings(), "Key"+Str(i))
    Test\MapList()\MapOfStrings() = Str(i)
  Next i
  
  ForEach Test\MapList()\MapOfStrings()
    Debug MapKey(Test\MapList()\MapOfStrings())
  Next
EndProcedure


Procedure main()
  InitMap(#MapOfStringsA)
EndProcedure


AddElement(Test\MapList())
AddElement(Test\MapList())
AddElement(Test\MapList())

main()
dougmo52usr
User
User
Posts: 62
Joined: Mon Jul 18, 2016 6:43 pm

Re: Map access questions

Post by dougmo52usr »

Your method certainly works. I was hoping that I could avoid passing a map in a structure by creating a map reference.

In DoSomething1, Global MapA is altered through a reference. In DoSomething2, Global MapA is altered directly. In the Procedures, MapA syntax looks exactly the same.

Is there a way to create a DoSomething3 with a local variable that references a map similar to how DoSomething1 did when it passed MapA? I was hoping that @MapA() would give the MapA address, but it apparently gives the address of the current element. On the other hand, DoSomething1(Map MapA.s()) gets the MapA address.

Code: Select all

; create a global map
Global NewMap MapA.s()

; access a global map by reference 
Procedure DoSomething1(Map MapA.s()) 
  ; add an element to a global map
  AddMapElement(MapA(),"Key1")
  ; set it's value
  MapA() = "Value1"
EndProcedure

; access a global map directly
Procedure DoSomething2()
  ; add an element to a global map
  AddMapElement(MapA(),"Key1")
  ; set it's value
  MapA() = "Value1"
EndProcedure

Procedure DoSomething3()
  Protected RefToMapA = ????
  ; add an element to a global map
  AddMapElement(RefToMapA(),"Key1")
  ; set it's value
  RefToMapA() = "Value1"  
EndProcedure  
Post Reply