AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Eine TCollection sortieren!

Ein Thema von LoCrux · begonnen am 18. Mär 2008 · letzter Beitrag vom 15. Apr 2008
Antwort Antwort
Benutzerbild von LoCrux
LoCrux

Registriert seit: 5. Mär 2007
Ort: Gwang-Yang-City
48 Beiträge
 
Delphi 2009 Enterprise
 
#1

Eine TCollection sortieren!

  Alt 18. Mär 2008, 10:00
Items einer TCollection sortieren!

Vielleicht ist das fuer den einen oder anderen auch interessant.
Funktioniert und getestet in Delphi 7 Enterprise.

Delphi-Quellcode:
interface {PART}

type
  
  TMyCollectionItem = CLASS(TCollectionItem)
  private
    .
    FSortIndex : Integer;
    .
  protected
    .
    .
  public
    .
    property SortIndex:Integer read FSortIndex write FSortIndex default -1;
    .
  end;


  TMyCollection = CLASS(TCollection)
  private
    .
    .
  protected
    .
    .
  public
    .
    procedure Sort;
    .
  end;


implementation {PART}

  //-----------------------------------------------------//
  // //
  //-- TCollection Hack to Access Private Declarations --//
  // //
  //-----------------------------------------------------//
  // //
  // Org. Declaration order of TCollecion in Classes //
  // //
  // TCollection = class(TPersistent) //
  // private //
  // FItemClass: TCollectionItemClass; //
  // FItems: TList; //
  // . //
  // . //
  //-----------------------------------------------------//
  // //
  // To Access eg. FItems of your TCollection //
  // //
  // SC := TShadowedCollection(Self).FItems; //
  // //
  //-----------------------------------------------------//

  {$HINTS OFF}
  TShadowedCollection = class(TPersistent)
  private
    FItemClass: TCollectionItemClass;
    FItems: TList;
  end;
  {$HINTS ON}


procedure TMyCollection.Sort;
var
  sc : TList;
  i : integer;

  procedure _QuickSort(L, R: Integer);
  var
    I, J, P : Integer;
    Save : TCollectionItem;
  begin
    repeat
      I := L;
      J := R;
      P := (L + R) shr 1;
      repeat
        while TMyCollectionItem(Items[I]).SortIndex<TMyCollectionItem(Items[P]).SortIndex do Inc(I);
        while TMyCollectionItem(Items[J]).SortIndex>TMyCollectionItem(Items[P]).SortIndex do Dec(J);
        if I <= J then begin
          Save := sc.Items[I];
          sc.Items[I] := sc.Items[J];
          sc.Items[J] := Save;
          if P = I then
            P := J
          else if P = J then
            P := I;
          Inc(I);
          Dec(J);
        end;
      until I > J;
      if L < J then _QuickSort(L, J);
      L := I;
    until I >= R;
  end;


begin
  {$WARNINGS OFF}
  if (count>1) {OTHERWISE MAKES NO SENSE}
  then begin
    //-- THE TCOLLECTION HACK TO ACCES FITMES OF THE ANCESTOR CLASS --//
    sc := TShadowedCollection(Self).FItems;
    //-- NOW CALCULATING OR DEFINIG THE SORT CRITERIA --//
    for i := 0 to sc.Count-1
      do TMyCollectionItem(sc.Items[i]).SortIndex := WhatEverToCalculateWith(sc.Items[i]); {Ein Integer Kriterium}
    //-- AND DO THE LIMBO --//
    _QuickSort(0,count-1);
  end;
  {$WARNINGS ON}
end;
WhatEver koennte z.B. ein Funktion sein aka:

Delphi-Quellcode:
 

function TMyCollection.WhatEverToCalculateWith(AItem:TCollectionItem):integer;
var
  CastedItem : TMyCollectionItem;
begin
  CastedItem := TMyCollectionItem(AItem);
  .
  .
  result := TheResultOfYourCalculation; // SORRY ABER MUSS HIER MAL ABSTRAKT BLEIBEN
end;



Alternativ geht es auch so. Hier muesst Ihr Euer Kriterium aber vorher igendwie definieren.

Delphi-Quellcode:

//-----------------------------------------------------------------//
// //
// Defined in Classes: //
// //
// TListSortCompare = function (Item1, Item2: Pointer): Integer; //
// //
//-----------------------------------------------------------------//

function compare(Item1, Item2: Pointer): Integer; {=TListSortCompare}
var v1,v2 : integer;
begin
  result := 0;
  v1 := TMyCollectionItem(Item1).SortIndex; {Oder Anderes Kriterium}
  v2 := TMyCollectionItem(Item2).SortIndex; {Oder Anderes Kriterium}
  if (v1>v2)
    then result:=1
    else if (v1<v2)
         then result := -1;
end;


procedure TMyCollection.Sort;
var
  sc : TList;

begin
  {$WARNINGS OFF}
  if (count>1) {OTHERWISE MAKES NO SENSE}
  then begin
    //-- THE TCOLLECTION HACK TO ACCES FITMES OF THE ANCESTOR CLASS --//
    sc := TShadowedCollection(Self).FItems;
    //-- AND DO THE LIMBO --//
    sc.Sort(compare); // ALTERNATIVE - BUT MAYBE MORE CALCULATIONS
  end;
  {$WARNINGS ON}
end;

{$WARNINGS ON/OFF} und {$HINTS ON/OFF} damit der Compiler nicht meckert (unsichere Typumwandlung).

Der Hack wurde so oder so aehnlich schon mal HIER AUF DELPHIPRAXIS besprochen.

Edits: Tippfehler
“C++ is an insult to the human brain.” [Niklaus Wirth]

2B OR NOT 2B (.. THAT IS FF)
  Mit Zitat antworten Zitat
triPunkt

Registriert seit: 17. Feb 2003
Ort: Berlin
15 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Eine TCollection sortieren!

  Alt 15. Apr 2008, 17:09
Das sollte übrigens auch einfacher gehen mittels:

Delphi-Quellcode:
procedure TMyCollection.Sort(CompareCallback: TListSortCompare);
begin
  TShadowedCollection(Self).FItems.Sort(CompareCallback);
end;
Schöne Grüsse!
tripunkt GmbH // Berlin
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:39 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz