Remove not removing..

BlitzMax Forums/BlitzMax Programming/Remove not removing..

Tibit(Posted 2005) [#1]
When I call MyList.Remove( MyObject ) in a Eachin-MyList-Loop is there anyway I can get the message "Not Found" ? Because I do but it seems impossible because to call it assumes it exsists. There is another factor in this I know it.. Can anyone figure out how a remove() would not work?

It would be eqvivialent to this not working:

Global List:TList
For C:Car = EachIn List
If List.Contains(C) DebugLog "Found it!" Else DebugLog "Not Found!"
Next

How can I ever get a "Not Found" from the above? I loop the list I check. But I get "Not Found" on all objects. Still it's the same list.

I did a MyList.Count() before and after the remove - it did not change so I assume it's not a flushmem issue.


Perturbatio(Posted 2005) [#2]
if not C?


Cajun17(Posted 2005) [#3]
I would think it has something to do with removing the link of the current object in the list before the For loop has a chance to get the next value.

I don't know if that's the problem for sure but this works

global list:TList
for i = 1 to list.Count()
    list.RemoveLast()
next

or

while (not list.IsEmpty())
    list.RemoveLast()
wend



Regular K(Posted 2005) [#4]
while (not list.IsEmpty())
list.RemoveLast()
wend

I think you missed a bracket.


Tibit(Posted 2005) [#5]
@Perturbatio the list only contain cars in that example.

@Cajun17, RemoveLast() or RemoveFirst() works. But I need to delete a specific object. Still you might be on to the problem. But this does not work either:
		For  Local NR = 1 To List.Count()
			Local C:Car = Car( List.ValueAtIndex(NR) )    
			If C = Null DebugStop()
			If List.Remove(C) DebugLog "Deleted!" Else DebugLog "Not Found!"
		Next
I check the list in the debugger and it does indeed contain two of these very types, C is not null..

I loop a lists of a certain type, like cars. I find the car I want to remove by ID or health or whatever in a simple if-statement. Now I have an object from this list. I take that Object C and remove it from this List: MyList.Remove( C ). That C was <> null or the loop woudn't have looped. But the remove function tells me that object does not exsist in that list?!

There have to be some other factor. I don't know how to continue debugging this. It seems like a paradox. "Found it, but it does not exsist.."


Cajun17(Posted 2005) [#6]
Well I was wrong about the loop idea. The list is created in such a way that you can do a for/eachin and remove them all. Your problem is that you forgot to implement a compare method for your type.

I did some fooling with the list and the remove method works if you do:
Strict 

'make a type
Type mytype
	Field value:Int
	
	Method compare(c:Object)
		Return (value-mytype(c).value)
	End Method
End Type

'make a list
Local list:TList=New TList

'initialize the list
Local a:mytype
For Local i:Int=0 To 9
	a=New mytype
	a.value=i
	list.AddFirst(a)
Next

'create an initialize a type to remove
Local b:mytype=New mytype
b.value=5

'remove the type
list.Remove(b)

'check the list for the removed object
For b=EachIn list
	Print b.value
	Print
Next

'remove all the other objects
For b=EachIn list
	list.remove(b)
Next

'check the list again
For b=EachIn list
	Print b.value
	Print
Next


Also just to be picky your loop above wouldn't work because if you delete the first element then the second element will become the first and the third will become the second. You'd end up deleting only every other element.


Dreamora(Posted 2005) [#7]
that is not needed

compare is only needed if you plan to use the sort method of lists


Cajun17(Posted 2005) [#8]
First the compare method is called by these functions: sort, contains, findlink and remove calls FindLink and therefore indirectly calls compare.

Depending on how you're using the list implmenting a compare method may or may not be useful. If you don't implement one the parent's compare method will be called.

Object.Compare returns the difference in memory addresses of the 2 objects so even objects identical in values will not be found equal.

If you want to remove every object in a list just do
list.Clear().

If you want to remove an object based on some value just implement a compare for the type and wrap the value in the type and call the list.remove() method.
-or-
Without the compare method do this.
for a:mytype = eachin mylist
    if a.value=specificValue then mylist.remove(a)
next

That can be very wasteful if the list is long because you have to find the object to call remove on it, but remove has to go find the object again before it can be removed.


Tibit(Posted 2005) [#9]
Yes! That's it! You got the point. I have a compare method in my type. And that's probably what screws up the remove method! So it's the other way around. I'll look into this, I'll be right back.


Tibit(Posted 2005) [#10]
Yes thanks Cajun! My compare method was not functioning properly. When I used yours it works. You don't know how much this helped me. I never figured that the compare method was used in findlink(). Thanks again!


Dreamora(Posted 2005) [#11]
might be that it is used in find link. but if you do not implement it (as you don't use sort), it will be used the default one which does not mess with stuff :)


Cajun17(Posted 2005) [#12]
No problem, Wave. :)

For future refrence the compare method returns an interger such that 0 signifies equality, less than 0 signifies less than, greater than 0 signifies greater than and any non-zero means not equal.