Problem with changing the order of elements within a TList


I’ve got the following simple problem:
I fill a TList, but afterwards I want to change the order. But I fail in doing some simple add and remove.


i fill a tlist with some strings:

TList *t = new TList()
t->Add( new TObjString( "1" ) )
t->Add( new TObjString( "2" ) )
t->Add( new TObjString( "3" ) )
t->Add( new TObjString( "4" ) )

if i print the list, i get:

TObjString = 1
TObjString = 2
TObjString = 3
TObjString = 4

… which is fine.
Now I add the last element as the first (thus, I got element “4” twice, … at position 0 and 4)

t->AddFirst( t->Last() )
TObjString = 4
TObjString = 1
TObjString = 2
TObjString = 3
TObjString = 4

… next step: I remove the last element.

TObjString = 1
TObjString = 2
TObjString = 3
TObjString = 4

… but actually the first element (which was the last one added) is removed. Why?

How is changing the order of elements supposed to be done with a TList?


Hehe! That’s because RemoveLast is implemented as
Remove(Last()); so it traverses the list and removes the first object, “equal” to Last.

Lol, even RemoveAt will not work as you want. Really interesting logic of TList. It first will obtain pointer At(idx) and after that it’ll call Remove(ptr). :laughing:


ok, … now that I know how the logic is working I know how to work with it.

I simply have to get the “Last()” element and store it outside the list. Then I do “RemoveLast()” and afterwards I “AddFirst()” the stored element.


  • peter

Yes, the this can be improved in case of duplicates in a sequential collection (where first and last makes sense).

Cheers, Fons.

Well, I was a bit incorrect: RemoveAt/RemoveLast/etc. come from TSeqCollection, but as I can see from TList header, TList has its own methods to work directly with TList (for your specific case only :frowning: - I mean only the last object in TList).
For TList you can use TObjLink object instead of TObject * pointer.
For example,

TList a;
a.Add(new TObjString(“1”));
a.Add(new TObjString(“2”));
a.Add(new TObjString(“3”));
a.Add(new TObjString(“4”));
//Now, remove the last element:

Or you can obtain link for first object : a.FirstLink(), after that, “increment” such a link : lnk->Next() (or lnk->Prev()), so you can iterate
a list as if you use std::list::iterator (not exactly, but similar).
And you can remove pointed object a.Remove(lnk);

And do not forget about memory management - it’s up to you to free memory correctly.