How to make TCollection that sorts on demand? 
Author Message
 How to make TCollection that sorts on demand?

I want to make a descendent of TSortedCollection that can be sorted on
demand, using different rules. For example, if it is holding a list records
with names and phone numbers, I want it to be able to sort the items based
on the name field, and then when needed, resort the items based on the phone
field.

If anyone has any suggestions or knows what is the most efficient way of
doing this, please tell me.

I thought of using a flag that Compare could check to determine the method
of sorting. Then when the collection needs to be resorted, all its items can
be inserted into a temporary collection, and re-inserted one by one into the
original collection. But this method seems to be messy and may take up too
much time (since the collection could be quite large). Does anyone have a
better way?



Wed, 18 Jun 1902 08:00:00 GMT  
 How to make TCollection that sorts on demand?
zimmy schrieb:
Quote:

> I want to make a descendent of TSortedCollection that can be sorted on
> demand, using different rules. For example, if it is holding a list records
> with names and phone numbers, I want it to be able to sort the items based
> on the name field, and then when needed, resort the items based on the phone
> field.

> If anyone has any suggestions or knows what is the most efficient way of
> doing this, please tell me.

> I thought of using a flag that Compare could check to determine the method
> of sorting. Then when the collection needs to be resorted, all its items can
> be inserted into a temporary collection, and re-inserted one by one into the
> original collection. But this method seems to be messy and may take up too
> much time (since the collection could be quite large). Does anyone have a
> better way?

You have to create your own descendant of the TSortedCollection anyway,
so it is easy to include a variable to distinguish sorting methods:

Type TSort = (NoSort,NameSort,DateSort,....);
  TMySortedCollection = Object(TSortedCollection)
                          Sor : TSort;
                          Constructor Init....
                          Function Compare(Key1,Key2 : Pointer):Integer;
virtual;
                          ....
                          Procedure Resort;
                        End;

function TMySortedCollection.Compare(Key1,Key2 : Pointer):Integer;
Begin
  Case Sor of
   NoSort : Compare := 1;
 NameSort : if PMyRec(Key1)^.Name > PMyRec(Key2)^.Name then
              Compare := 1
            else
              Compare := -1;
 DateSort : if PMyRec(Key1)^.Date = PMyRec(Key2)^.Date then
              Begin
                if PMyRec(Key1)^.Name > PMyRec(Key2)^.Name then
                  Compare := 1
                else
                  Compare := -1;
              End
            else
              if PMyRec(Key1)^.Date = PMyRec(Key2)^.Date then
                Compare := 1
              else
                Compare := -1;
  End; {case}
End;

For re-sorting you must write your own resort procedure, which
uses Compare, but runs some quicksort or bubble sort procedure
when invoked, on the Item list. You can (of course) swap the
pointers in the list, not the whole records.

Procedure TMySortedCollection.Resort;
Var I : Integer;
    done : Boolean;
  Procedure Swap;
  Var P : Pointer;
  Begin
    P := Items^[I];
    Items^[I] := Items^[I+1];
    Items^[I+1] := P;
    done := false;
  End;
Begin
  if Count < 2 then exit;
  repeat  {bubble}
    done := true;
    for I := 0 to count-2 do
      begin
        if Compare(Items^[I],Items^[I+1]) < 0 then
          Swap;
      End;
  until done; { hope this scratch proc is correct ... ;-) }
End;

Franz Glaser



Wed, 18 Jun 1902 08:00:00 GMT  
 How to make TCollection that sorts on demand?
Hi,

I had a similar problem.  I wanted to sort either an ID or a Name.  Here is
a chunk of the code I used :

{ TSortedCustDB }

function TSortedProdDB.Compare(Key1, Key2: Pointer): Integer;
begin
  if PString(Key1)^ < PString(Key2)^ then
    Compare := -1
  else if PString(Key1)^ > PString(Key2)^ then
    Compare := +1
  else
    Compare := 0
end;

function TSortedProdDB.KeyOf(Item: Pointer): Pointer;
begin

end;

function ProductSearchRecord(ProdDB: PSortedProdDB; Key: String; st:
Integer): PProduct;
var
  Result: PProduct;

  ID : ProdIDStr;
  Desc : ProdDescStr;
  Cost : ProdCostStr;

  function MatchesID(P: PProduct): Boolean; far;
  begin
    MatchesID := Pos(Key, P^.ID) = 1
  end;

  function MatchesDesc(P: PProduct): Boolean; far;
  begin
    MatchesDesc := Pos(Key, P^.Desc) = 1
  end;

begin

  case st of


  else
    Result := nil
  end;

  ProductSearchRecord := Result;
end;

Quote:

>I want to make a descendent of TSortedCollection that can be sorted on
>demand, using different rules. For example, if it is holding a list records
>with names and phone numbers, I want it to be able to sort the items based
>on the name field, and then when needed, resort the items based on the
phone
>field.

>If anyone has any suggestions or knows what is the most efficient way of
>doing this, please tell me.

>I thought of using a flag that Compare could check to determine the method
>of sorting. Then when the collection needs to be resorted, all its items
can
>be inserted into a temporary collection, and re-inserted one by one into
the
>original collection. But this method seems to be messy and may take up too
>much time (since the collection could be quite large). Does anyone have a
>better way?



Wed, 18 Jun 1902 08:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. New supply and demand page

2. Shell sort vs. Comb sort (was: sorting arrays)

3. FPC: Wrong behavior in nested use of TCollection.ForEach

4. What are TCollection's accessor methods?

5. Problem with TCollection and DLLs

6. TCollection and XMS

7. ??C++ analog of TCollection ??

8. Tcollection into Clipboard

9. Bug in tCollection.ForEach?

10. Hashing data container object (TCollection?) wanted

11. Fast copying records in sorted order / was Sorting

12. Most efficient sort text file routine, sort algorithms

 

 
Powered by phpBB® Forum Software