How do I use TMap?

BlitzMax Forums/BlitzMax Beginners Area/How do I use TMap?

Telemental(Posted 2005) [#1]
Does anybody have any idea how to implement TMap? I'd like to create a hash, but I can't seem to use EachIn to cycle through keys nor retrieve a key with ValueForKey(string) [I just get an object cannot be converted error].


gman(Posted 2005) [#2]
im using TMap for something im working on and while figuring out how to use it i wrote up this sample. based on some of the things i encountered and feel are missing im not sure if its complete yet. this based on the fact that TNode.Remove() fails an assert out of the box and that things like a NodeCount() method are not there. also, i dont see the need for TEnumer. it appears to just store a reference to the real enumerator object so my assumption is there probably more planned for it. TMap is functional as it stands.
Strict
Framework BRL.Basic
Import BRL.Map

Local themap:TMap=New TMap

' items to store in the map
Type item
	Field val:String
	Function create:item(text:String)
		Local retval:item=New item
		retval.val=text
		Return retval
	EndFunction
EndType

' create some items to add
Local val1:item=item.create("this is test1")
Local val2:item=item.create("this is test2")

' insert some nodes using a text key.  you can use any object for the key, but make sure you 
' properly implement the Compare() method.
themap.Insert("test1",val1)
themap.Insert("test2",val2)

Print("")
Print("-----------------------------------")
Print("Enumerate Keys")
Print("-----------------------------------")

' get the key enumerator
Local keyenum:TKeyEnum=TKeyEnum(themap.Keys().ObjectEnumerator())

' loop through the enumerator showing each key
While keyenum.HasNext()
	Print(keyenum.NextObject().ToString())
Wend

Print("")
Print("-----------------------------------")
Print("Enumerate Values")
Print("-----------------------------------")

' get the key enumerator
Local valenum:TValueEnum=TValueEnum(themap.Values().ObjectEnumerator())

' loop through the enumerator showing each value for the objects of type item
While valenum.HasNext()
	Print(item(valenum.NextObject()).val)
Wend

Print("")
Print("-----------------------------------")
Print("Enumerate Nodes")
Print("-----------------------------------")

Local nodeenum:TNodeEnum=themap.ObjectEnumerator()
While nodeenum.HasNext()
	Local temp:TNode=TNode(nodeenum.NextObject())
	Print("KEY: "+temp.Key().ToString())
	Print("VAL: "+item(temp.Value()).val)
Wend

Print("")
Print("-----------------------------------")
Print("Is key present?")
Print("-----------------------------------")

' check for test3
If Not themap.ValueForKey("test3") Then Print("test3: doesnt exist") Else Print("test3: its there")

' add test3
Local val3:item=item.create("this is test3")
themap.Insert("test3",val3)
' check for test3
If Not themap.ValueForKey("test3") Then Print("test3: doesnt exist") Else Print("test3: its there")

Print("")
Print("-----------------------------------")
Print("Getting value based on key")
Print("-----------------------------------")

' find the item
Local tempitem:item=item(themap.ValueForKey("test1"))

' be sure to check for null
If tempitem Then Print("test1 value is: '"+tempitem.val+"'") Else Print("could Not locate test1")

Print("")
Print("-----------------------------------")
Print("Finding TNode based on key")
Print("This is a little confusing because the parameter for TMap.FindNode says 'value:Object'")
Print("leading you to believe that you need to pass the value object instead of the key.  It")
Print("is in fact the _key_ that you need to pass.")
Print("-----------------------------------")

Local tempnode:TNode=themap.FindNode("test1")

' print out the key
Print(tempnode.Key().ToString())
' print out the item value
Print(item(tempnode.Value()).val)

Print("")
Print("-----------------------------------")
Print("Key based removal")
Print("-----------------------------------")

' check for test2
If Not themap.ValueForKey("test2") Then Print("test2: doesnt exist") Else Print("test2: its there")
' remove the item
themap.Remove("test2")
' check for test2
If Not themap.ValueForKey("test2") Then Print("test2: doesnt exist") Else Print("test2: its there")

Print("")
Print("-----------------------------------")
Print("Node based removal (doesnt appear to be working)")
Print("-----------------------------------")

'Print("removing "+tempnode.Key().ToString())
'tempnode.Remove()
' check for test1
'If Not themap.ValueForKey("test1") Then Print("test1: doesnt exist") Else Print("test1: its there")

Print("")
Print("-----------------------------------")
Print("Clearing the map")
Print("-----------------------------------")

' remove all nodes
themap.Clear()

Print("")
Print("-----------------------------------")
Print("Checking that the map is empty")
Print("-----------------------------------")

' make sure its empty
If Not themap.FirstNode() Then Print("map is empty") Else Print("map is not empty")



Tibit(Posted 2005) [#3]
GMan many thanks, this really helped!

Here is the simplified version of TMap. I use Strings both as objects and Strings. A bit easier to read. Otherwise it's the same as above.

'Initiate TMap
Global Map:TMap = New TMap

' A D D
Key$ = "Card on Hand"
Map.Insert( Key , "Dimond" )
Map.Insert( Key , "Harts" )'Will overwrite "Dimond"

Key$ = "Marker1"
Map.Insert( Key , "Not Blue" )

Key$ = "Marker2"
Map.Insert( Key , "Red" )

Key$ = "Marker1"
Map.Insert( Key , "Blue" )' Write 'Blue' to Node 'Marker1'

' F I N D
Key$ = "Card on Hand"' Yes the key is caSe SensItivE
If Map.FindNode( Key ) 		Print "Key Found" Else Print "Key NOT Found"

' F I N D   A L L   K E Y S
Print "------ All Keys in Map -------"
Local n=0
For S$ = EachIn Map.Keys()
	n:+1
	Print n+". Key in Map: "+S	
Next

' F I N D   A L L   O B J E C T S

Print "------ All Objects in Map -------"
n=0
For S$ = EachIn Map.Values()
	n:+1
	Print n+". Object in Map: "+S
Next

' F I N D   A L L   N O D E S

Print "------ All Nodes in Map -------"
n=0
For Node:TNode = EachIn Map
	n:+1
	Print n+". Key  : "+Node.Key().ToString()
	Print n+". Value: "+Node.Value().ToString()
Next


' R E M O V E

'Remove key
Key$ = "Marker1"
Map.Remove( Key )

'Remove A Key based on the Object/Value
ObjectInQuestion$ = "Red"
For Node:TNode = EachIn Map
	If Node.Value() = ObjectInQuestion$ Node.Remove()
Next



Rimmsy(Posted 2005) [#4]
There are map functions? Oh man. the amount of time I could have saved if I'd just poked around.

Thanks guys.


gman(Posted 2005) [#5]
@Wave - glad i could help :)