Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2014-03

Elegant way to switch sort mechanism in TSortedCollection?

12 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jim Leonard

I'm working on a project that utilizes a TSortedCollection to help keep items sorted during processing. There is a need to re-sort the collection by different criteria on-demand as the program runs. (Different sort orders are an integral part of the processing.)

Unless I'm missing something, TSortedCollection lacks the ability to change the Compare method after initialization and/or explicitly re-sort the collection on-demand. I was planning on handling each new (re)sort by:

1. Initializing a new TSortedCollection with the desired Compare method
2. Copying the contents from the old collection to the new one
3. Swap collection pointers; destroy the old collection.

This works without much penalty because the collection will never get beyond a reasonable size, but the implementation makes me cringe. Is there a more elegant way to do this (without writing my own sort routines for a plain TCollection)?

Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag!

Reply by email

Jim Leonard
to Jim Leonard

Sorry, some Turbo Pascal-isms in my initial mail -- I see that FreePascal's TCollection class has an explicit .Sort method so this helps me re-sort on demand, but it doesn't help me switch the Compare method. So, my question still stands.

Jim Leonard wrote 17 lines
I'm working on a project that utilizes a TSortedCollection to help keep items sorted during processing. There is a need to re-sort the collection by different criteria on-demand as the program runs. (Different sort orders are an integral part of the processing.) Unless I'm missing something, TSortedCollection lacks the ability to change the Compare method after initialization and/or explicitly re-sort the collection on-demand. I was planning on handling each new (re)sort by: 1. Initializing a new TSortedCollection with the desired Compare method 2. Copying the contents from the old collection to the new one 3. Swap collection pointers; destroy the old collection. This works without much penalty because the collection will never get beyond a reasonable size, but the implementation makes me cringe. Is there a more elegant way to do this (without writing my own sort routines for a plain TCollection)?
Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag!

Reply by email

Philippe
to Jim Leonard: I'm working on a project that utilizes a TSortedCollection to help keep items sorted…

using the example at
http://acm.msu.ru/mkoshp/fpc/rtl/objects/tsortedcollection.html

may
something this way ...

Type
TMethod = ( method_type_1, method_type_2,
method_type_3);
PMySortedCollection = ^TMySortedCollection;
TMySortedCollection = Object(TSortedCollection)
 method : TMethod;
Function Compare (Key1,Key2 : Pointer): Sw_integer; virtual;
 procedure
setMethod( const m : TMethod);
end;
Implementation
Uses MyObject;
Function TMySortedCollection.Compare (Key1,Key2 : Pointer)
:sw_integer;
begin
 case method of
 method_type_1:
Compare:=PMyobject(Key1)^.GetField - PMyObject(Key2)^.GetField;
method_type_2: Compare:=PMyobject(Key2)^.GetField -
PMyObject(Key1)^.GetField;
 method_type_3:
Compare:=PMyobject(Key1)^.GetField - 2 * PMyObject(Key2)^.GetField;
end;
end;
procedure TMySortedCollection.setMethod( const m :
TMethod);
begin
 method := m;

....

end;
Jim Leonard wrote
I'm working on a project that utilizes a

TSortedCollection to help keep

items sorted during processing. There

is a need to re-sort the

collection by different criteria on-demand

as the program runs.

(Different sort orders are an integral part of

the processing.)

Unless I'm missing something, TSortedCollection

lacks the ability to

change the Compare method after initialization

and/or explicitly re-sort

the collection on-demand. I was planning on

handling each new (re)sort by:

1. Initializing a new

TSortedCollection with the desired Compare method

2. Copying the

contents from the old collection to the new one

3. Swap collection

pointers; destroy the old collection.

This works without much

penalty because the collection will never get

beyond a reasonable

size, but the implementation makes me cringe. Is

there a more elegant

way to do this (without writing my own sort

routines for a plain

TCollection)?

Reply by email

Jim Leonard
to Philippe
Philippe wrote
Type TMethod = ( method_type_1, method_type_2, method_type_3);

Ah, clever -- create a Compare that switches based on what I tell it to do. I like that, but as far as I can tell there's no way to tell a TSortedCollection to "resort" -- it's kept sorted only through inserts and deletes.

Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag!

Reply by email

Frederic Da Vitoria
to Jim Leonard

2014-03-12 21:56 GMT+01:00 Jim Leonard :

Show quoted text 11 lines
On 3/12/2014 2:30 PM, Philippe wrote: > Type > TMethod = ( method_type_1, method_type_2, method_type_3); > Ah, clever -- create a Compare that switches based on what I tell it to do. I like that, but as far as I can tell there's no way to tell a TSortedCollection to "resort" -- it's kept sorted only through inserts and deletes.

You (or the user) will never need to resotre the first order? I am asking because you could as well simply create one SortedCollection for each sort order and systematically insert each item in all those collections. The overhead would be in the initial loading, but then switching would be instantaneous.

Frederic Da Vitoria (davitof) Membre de l'April - « promouvoir et défendre le logiciel libre » - http://www.april.org

Reply by email

Philippe
to Frederic Da Vitoria

solution may depend on the way the collection is used. load once? many inserts and deletes? ... the time you have to switch from one sort to another ... and the size of the collection ...

you could

- store
the actual collection to a TMemoryStream,

- destroy the collection,

- Load then a new collect to be sort with different method ...

2014-03-12 21:56 GMT+01:00 Jim Leonard :Em

Frederic Da Vitoria wrote
> On 3/12/2014 2:30
Philippe wrote
> >> Type >> TMethod = ( method_type_1,
method_type_2, method_type_3);
> > Ah, clever -- create a Compare

that switches based on what I tell it to do. I like that, but as far as I can tell there's no way to tell a TSortedCollection to "resort" -- it's kept sorted only through inserts and deletes.

You (or the user)

will never need to resotre the first order? I am asking because you could as well simply create one SortedCollection for each sort order and systematically insert each item in all those collections. The overhead would be in the initial loading, but then switching would be instantaneous.

Show quoted text 6 lines
-- Frederic Da Vitoria (davitof) Membre

de l'April - « promouvoir et défendre le logiciel libre » - http://www.april.org [2]

Reply by email

Jim Leonard
to Frederic Da Vitoria: 2014-03-12 21:56 GMT+01:00 Jim Leonard : You (or the user) will never need to resotre the…
Frederic Da Vitoria wrote 5 lines
You (or the user) will never need to resotre the first order? I am asking because you could as well simply create one SortedCollection for each sort order and systematically insert each item in all those collections. The overhead would be in the initial loading, but then switching would be instantaneous.

The problem is, the workflow makes changes to the list, re-sorts, and then this repeats. It's a processing algorithm for graphics. So while I could make several sorted lists, I'd have to manipulate/change them all simultaneously.

Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag!

Reply by email

Jim Leonard
to Philippe: solution may depend on the way the collection is used. load once? many inserts and…
Philippe wrote 7 lines
you could - store the actual collection to a TMemoryStream, - destroy the collection, - Load then a new collect to be sort with different method ...

Yes, that's what I'm doing now for every re-sort.

I'll check the source and see if I can override any of the methods, but if not, it sounds like this is what I'll have to do unless I want to write my own custom data structure for this process.

Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag!

Reply by email

Jim Leonard
to Jim Leonard
Jim Leonard wrote 10 lines
On 3/12/2014 6:58 PM, Philippe wrote: > you could > > - store the actual collection to a TMemoryStream, > > - destroy the collection, > > - Load then a new collect to be sort with different method ... Yes, that's what I'm doing now for every re-sort.

Actually, sorry, that's not *exactly* what I'm doing -- I'm creating a new TSortedCollection, using ForEach to iterate through the old collection to Insert into the new one, and then destroying the old one. This copies only pointers (and runs through the Compare method) and is actually pretty fast -- it's just not elegant.

If I stored the entire thing to a memory stream, it would copy all of the data and every re-sort would go pretty slowly.

Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag!

Reply by email

Frederic Da Vitoria
to Jim Leonard

2014-03-13 15:56 GMT+01:00 Jim Leonard :

Show quoted text 24 lines
On 3/13/2014 9:49 AM, Jim Leonard wrote: > On 3/12/2014 6:58 PM, Philippe wrote: > >> you could >> >> - store the actual collection to a TMemoryStream, >> >> - destroy the collection, >> >> - Load then a new collect to be sort with different method ... >> > > Yes, that's what I'm doing now for every re-sort. > Actually, sorry, that's not *exactly* what I'm doing -- I'm creating a new TSortedCollection, using ForEach to iterate through the old collection to Insert into the new one, and then destroying the old one. This copies only pointers (and runs through the Compare method) and is actually pretty fast -- it's just not elegant. If I stored the entire thing to a memory stream, it would copy all of the data and every re-sort would go pretty slowly.

You are sorting only for display purposes? If so, maybe VirtualTreeView could do the trick.

Frederic Da Vitoria (davitof) Membre de l'April - « promouvoir et défendre le logiciel libre » - http://www.april.org

Reply by email

Jim Leonard
to Frederic Da Vitoria
Frederic Da Vitoria wrote
You are sorting only for display purposes?

No, re-sorting is part of the algorithm, which sorts a list of graphics elements and then inserts/splits/deletes the collection entries, and then repeats this process. The sort method can change each iteration depending on the number and status of the entries.

Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag!

Reply by email

Yann Mérignac
to Jim Leonard

Depending on the number of possible sort orders, may be it is better to have one collection by possible sort order and to permanently keep the collections sorted.

2014-03-13 22:26 GMT+01:00 Jim Leonard :

Show quoted text 19 lines
On 3/13/2014 3:49 PM, Frederic Da Vitoria wrote: > You are sorting only for display purposes? > No, re-sorting is part of the algorithm, which sorts a list of graphics elements and then inserts/splits/deletes the collection entries, and then repeats this process. The sort method can change each iteration depending on the number and status of the entries. -- Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag! _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email