Remove entry from TList

BlitzMax Forums/BlitzMax Beginners Area/Remove entry from TList

andre72(Posted 2007) [#1]
Hi,

I have a problem when I remove entries from a TList.
I try to move entries from one TList to an other using this code:


For Local t:trainer=EachIn trainer.ltrainers
Local y:Byte=Rand(3)
If y=3 Then
s.AddTrainer(t)
ListRemove trainer.ltrainers,t
EndIf
Next

The matter is that the entries are only cleaned and not deleted.
So I have ever 30 entries in the TList and the removed ones are empty.
But they should really be deleted after copying them to the other list.

Thanks,

Andre


H&K(Posted 2007) [#2]
RemoveLink( link:TLink )

As you are already scaning though the list you shouldnt use listremove anyway, cos it also then scans thought the list.


andre72(Posted 2007) [#3]
Thanks - but I changed the source like this (is that the right way?):

If y=3 Then
s.AddTrainer(t)
Local l:TLink=ListFindLink(trainer.ltrainers,t)
RemoveLink l
EndIf

The result is the same, 30 entries and the removed are empty ...


Gabriel(Posted 2007) [#4]
No, you're still wasting time searching for a link you could already have. The link is returned by ListAddLast, so just a field in the type for the link and store it. Then you can just use RemoveLink and skip ListFindLink.


andre72(Posted 2007) [#5]
Thanks for the information - I use now this way.
However I've still the same problem - every entry is only empty and not deleted...


Gabriel(Posted 2007) [#6]
Have all the TLinks gone out of scope?


H&K(Posted 2007) [#7]
Print more code.
Cos if you have removed the link, then the link shouldnt be there. If what you are saying is that the object is still there, well it should be because as you said you have moved it over to another list.

You are in fact not deleting any object, you are only deleting a link. So unless after the code the first Tlist still contains the same number of object and the new Tlist now has more objects then there isnt a problem.


Gabriel(Posted 2007) [#8]
I can't repeat the behaviour you're experiencing, so I can only assume it's a problem with your code or your interpretation of what's happening.

Does this code behave correctly for you?


SuperStrict

Type Thing
	Global List1:TList=New TList
	Global List2:TList=New TList
	Field Link:TLink
	
	Method New()
		Link=List1.AddLast(Self)
	End Method
	
	Function SwapLists()
		DebugLog "LISTS SWAPPED"
		For Local T:Thing=EachIn List1
			T.Link.Remove()
			T.Link=List2.AddLast(T)
		Next
	End Function
	
	Function PrintList1()
		Print "LIST 1"
		Local Counter:Int=0
		For Local T:Thing=EachIn List1
			Counter:+1
			Print "ENTRY "+Counter
		Next
		Print "LIST 1 DONE"
	End Function
	
	Function PrintList2()
		Print "LIST 2"
		Local Counter:Int=0
		For Local T:Thing=EachIn List2
			Counter:+1
			Print "ENTRY "+Counter
		Next
		Print "LIST 2 DONE"
	End Function
	
End Type



Local I:Thing
Local Count:Int

For Count=1 To 20
	I=New Thing
Next


Thing.PrintList1()
Thing.PrintList2()

Thing.SwapLists()

Thing.PrintList1()
Thing.PrintList2()




andre72(Posted 2007) [#9]
@Gabriel
Well, great - your code works well.
If there won't anybody point out the mistake in my one I'll try to rewrite it like this.

@H&K
Here's a working example (only some Defdata and unimportant code is cut).
Hope someboy point out my mistake...


Type trainer
Global ltrainers:TList
Field ltlink:TLink,name:String

Method New()
If Not ltrainers ltrainers=CreateList()
Local ltlink:TLink=ListAddLast(ltrainers,Self)
Self.ltlink=ltlink
End Method

Function AddTrainer:trainer(name:String)
Local t:trainer = New trainer
t.name=name
Return t
End Function
End Type

Type stable
Global lstables:TList
Field name:String
Field ltrainers:TList

Function AddStable:stable(name:String)
Local s:stable = New stable
s.name = name
Return s
End Function

Method New()
If Not lstables lstables=CreateList()
ListAddLast lstables,Self
ltrainers=CreateList()
End Method

Method AddTrainer:trainer(trainers:trainer)
Local t:trainer = New trainer
t=trainers
ListAddLast ltrainers,t
Return t
End Method
End Type

Local t:trainer
Local s:stable
Local name:String,x:Byte

For x=0 To 9
ReadData name
t=trainer.addtrainer(name)
Next

For x=0 To 2
ReadData name
s=stable.addstable(name)

SeedRnd MilliSecs()
For t=EachIn trainer.ltrainers
Local y:Byte=Rand(3)
If y>1 Then
s.AddTrainer(t)
t.ltlink.Remove
EndIf
Next
Next

Print "Items: " + CountList(trainer.ltrainers)

For s=EachIn stable.lstables
Print s.name
For t=EachIn s.ltrainers
Print "~t"+t.name
Next
Next

For t=EachIn trainer.ltrainers
Print "~tFree Trainer: " +t.name
Next

Print "Items: " + CountList(trainer.ltrainers)

DefData "Geli"
DefData "Frank"
DefData "Jochen"
DefData "Susi"
DefData "Doro"
DefData "Karl"
DefData "Jurgen"
DefData "Dieter"
DefData "Sigrid"
DefData "Babsi"

DefData "Test 1"
DefData "Test 2"
DefData "Test 3"


H&K(Posted 2007) [#10]
Method AddTrainer(trainers:trainer)
		
		ListAddLast Self.ltrainers,trainers
	
	End Method
When you where calling Stable.AddTrainer, you were adding the NEW Trainer to the original Trainer list, then even though you removed the link to the object, you had added it agian.

Dont forget when you were adding the trainer to a stable, you where not supposed to make a NEW trainer, simply moving which list it was on.


andre72(Posted 2007) [#11]
Thanks for the solution. I'll have a look and try to fix this ...