Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Listenobjekte sortieren (https://www.delphipraxis.net/84511-listenobjekte-sortieren.html)

schuetzejanett 17. Jan 2007 20:35


Listenobjekte sortieren
 
hallo,

ich habe eine Klasse Playercollection die Player in einer liste speichert
Eine eigenschaft der Klasse Player ist der integerwert score.
Nun wollte ich die einzelnen Spieler nach den Punkten(score) sortieren.

Dafür habe ich gedacht ich speichere die Player in einem array und wende auf dieses array ein sortierverfahren an.

Allerdings komme ich nun etwas durcheinander, wenn ich den quicksort anwende da ich immernur die punkte ändere aber nicht die player genau.
Wie sortiere ich also die punkte und nicht nur den punktestand?

Delphi-Quellcode:
procedure TPlayerCollection.SortScores(var field : Array of TPlayer) ;
var i : integer;
begin
  getField(field); //feld änhält Playerobjekte
  quicksort(field, 0, self.Count-1);
end;

procedure TPlayerCollection.quicksort(var Field: array of TPlayer; ilow,
  ihigh: integer);
var
   Low, High, Mid, T: Integer;
 begin
   Low := iLow;
   High := iHigh;
   Mid := Field[(Low + High) div 2].score;
   repeat
     while Field[Low].score < Mid do Inc(Low);
     while Field[High].score > Mid do Dec(High);
     if (Low <= High) then
     begin
       T := Field[Low].score;
       Field[Low].score := Field[High].score;
       Field[High].score := T;
       Inc(Low);
       Dec(High);
     end;
   until Low > High;
   if High > iLow then QuickSort(Field, iLow, High);
   if Low < iHigh then QuickSort(Field, Low, iHigh);
end;
oder würdet ihr mir ein anderes Suchverfahren empfeheln, da es sich um höchstens 10 Playerobjekte handelt die sortiert werden müssten.

Luckie 17. Jan 2007 21:05

Re: Listenobjekte sortieren
 
Wieso ein noch mal ein Array? Du hast doch schon alle Spieler in eine Objektlist. Schreib dir doch einfach eine Methode, die dir diese Liste sortiert. Wenn du deine Objektliste von TList abgeleitet hast, dann kannst du die Methode Exchange nutzen, um zwei Items zu vertauschen. Ein einfaches BubbelSort sollte reichen.

schuetzejanett 17. Jan 2007 21:25

Re: Listenobjekte sortieren
 
danke für den Tipp, an die Möglichkeit habe ich gar nicht gedacht.

Gausi 17. Jan 2007 21:43

Re: Listenobjekte sortieren
 
Eine TList oder TObjectlist hat auch eine Methode Sort. Dafür muss man nur eine Compare-Funktion angeben. Ein Beispiel wäre evtl. so:
Delphi-Quellcode:
// Eine Compare-Funktion könnte so aussehen
function ScoreSort(item1,item2:pointer):integer;
begin
    result := TPlayer(item1).score <= TPlayer(item2).Score;
end;

// Aufruf geht dann so
Playlist.Sort(ScoreSort);

mojo777 23. Jun 2007 19:00

Re: Listenobjekte sortieren
 
Delphi-Quellcode:
// Aufruf geht dann so
Playlist.Sort(@ScoreSort);

Tod787 4. Dez 2008 07:15

Re: Listenobjekte sortieren
 
Hi, habe ein ähnliches Problem allerdings hab ich das nicht ganz verstanden. Ich suche eine Funktion mit der ich aus meiner Objektliste das Objekt bestimmen kann, welches den kleinsten Wert im Atribut "Größe: Single" besitzt.

mkinzler 4. Dez 2008 07:24

Re: Listenobjekte sortieren
 
Wenn du das öfterst brauchst -> Liste nach diesem Feld sortieren, sonst durch liste gehen und kleinsten Wert und dessen Objekt merken

Relicted 4. Dez 2008 07:26

Re: Listenobjekte sortieren
 
wenn du nur den kleinsten Wert haben willst ohne die Liste zu sortieren dann:

Delphi-Quellcode:
var
  coKleinsterEintrag : TDeineKlasse;


if Self.Count > 0 then
  coKleinsterEintrag := Self.Items[0];

for i := 0 to Self.Count - 1 do
begin
  if Self.Items[i].Wert < coKleinsterEintrag.Wert then
    coKleinsterEintrag := Self.Items[i];
end;
so aufrufen wenn du dich innerhalb der Liste befindest, wenn du ausserhalb die Bestimmung durchführen willst dann das "Self." durch deine Objectlist ersetzen.

Gruß
reli

Tod787 4. Dez 2008 08:02

Re: Listenobjekte sortieren
 
Also ich hab das mal versucht bei mir zu übertragen allerdings funktioniert das noch nicht so richtig. Bei der If-Abfrage kommt eine Fehlermeldung dass bei MyObjectlist.Items[i].Groesse das Feld .Groesse nicht deklariert wäre.

Delphi-Quellcode:
function TMyClass.GetNextGroesse: TMyObject;
var i: Integer; coKleinsteGroesse : TMyObject;
begin
  if MyObjectlist.Count > 0 then
    coKleinsteGroesse := TMyObject(MyObjectlist.Items[0]);

  for i := 0 to MyObjectlist.Count - 1 do
    begin
      if MyObjectlist.Items[i].Groesse < coKleinsteGroesse.Groesse then
        coKleinsteGroesse := MyObjectlist.Items[i];
    end;
  result := KleinsteGroesse;
end;
Edit:

mit
Delphi-Quellcode:
if TMyObject(MyObjectlist.Items[i]).Groesse < coKleinsteGroesse.Groesse then
geht es jetzt :)

DeddyH 4. Dez 2008 08:05

Re: Listenobjekte sortieren
 
Und bei
Delphi-Quellcode:
TMyObject(MyObjectlist.Items[i]).Groesse
?

Relicted 4. Dez 2008 08:14

Re: Listenobjekte sortieren
 
Daher empfehle ich immer typisierte Listen...

Mach dir mal nen Project1.dpr und mach nen Loadfromfile in ne Stringliste und mach für jede Zeile nen Format( Liste[i],[Edit1.text] );
In das Edit schreibste dann einfach den Namen der Klasse (ohne das T am Anfang) für die die Liste sein soll... Hier mein "Template"


Delphi-Quellcode:
unit %sList;
                                                                                       
interface                                                                              
                                                                                       
uses                                                                                  
  Contnrs,                                                                            
  %s;                                                                      
                                                                                       
type                                                                                  
  T%sList = class( TObjectList )                                            
  protected                                                                            
    //* Protected functions..                                                          
    function GetItem(Index: Integer): T%s; reintroduce;                    
    procedure SetItem(Index: Integer; const Value: T%s); reintroduce;      
  public                                                                              
    //* Constructors.. don't forget to call "inherited"                              
    //constructor Create; overload;                                                    
    //constructor Create(AOwnsObjects: Boolean); overload;                            
                                                                                       
    //* List Functions & Propertys                                                    
    function Add(AObject: T%s): Integer; reintroduce;                      
    function Extract(Item: T%s): T%s; reintroduce;              
    function Remove(AObject: T%s): Integer; reintroduce;                    
    function IndexOf(AObject: T%s): Integer; reintroduce;                  
    procedure Insert(Index: Integer; AObject: T%s); reintroduce;            
    function First: T%s; reintroduce;                                      
    function Last: T%s; reintroduce;                                        
    property Items[Index: Integer]: T%s read GetItem write SetItem; default;
                                                                                       
    //* Insert your own functions here...                                              
  end;                                                                                
                                                                                       
implementation                                                                        

uses
  Windows,
  SysUtils;

{ T%sList }                                                                 
                                                                                       
function T%sList.Add(AObject: T%s): Integer;                    
begin                                                                                  
  result := inherited Add( AObject );                                                  
end;                                                                                  
                                                                                       
function T%sList.Extract(Item: T%s): T%s;            
begin                                                                                  
  result := inherited Extract( Item ) as T%s;                              
end;                                                                                  
                                                                                       
function T%sList.First: T%s;                                    
begin                                                                                  
  result := inherited First as T%s;                                        
end;                                                                                  
                                                                                       
function T%sList.GetItem(Index: Integer): T%s;                  
begin                                                                                  
  result := inherited GetItem( Index ) as T%s;                              
end;                                                                                  
                                                                                       
function T%sList.IndexOf(AObject: T%s): Integer;                
begin                                                                                  
  result := inherited IndexOf( AObject );                                              
end;                                                                                  
                                                                                       
procedure T%sList.Insert(Index: Integer; AObject: T%s);          
begin                                                                                  
  inherited Insert(Index,AObject);                                                    
end;                                                                                  
                                                                                       
function T%sList.Last: T%s;                                      
begin                                                                                  
  result := inherited Last as T%s;                                          
end;                                                                                  
                                                                                       
function T%sList.Remove(AObject: T%s): Integer;                  
begin                                                                                  
  result := inherited Remove(AObject);                                                
end;                                                                                  
                                                                                       
procedure T%sList.SetItem(Index: Integer;                                  
  const Value: T%s);                                                        
begin                                                                                  
  inherited SetItem(Index,Value);                                                      
end;                                                                                  

end.
Damit fällt dann das ekelige Typecasten TMyObject() weg!

Gruß
Reli

Tod787 4. Dez 2008 08:22

Re: Listenobjekte sortieren
 
@DeddyH

verstehe nicht was du damit meinst. So hab ich es doch gemacht. Oder haben wir uns zeitlich überschnitten?

Zitat:

Zitat von DeddyH
Und bei
Delphi-Quellcode:
TMyObject(MyObjectlist.Items[i]).Groesse
?

@Relicted
also eigentlich funktioniert das jetzt bei mir aber das mit der Typisierung interessiert mich zwar schon, weiß aber nicht so recht was du mir damit sagen willst. Auf den ersten Blick sieht das für mich komplizierter aus.

DeddyH 4. Dez 2008 08:26

Re: Listenobjekte sortieren
 
Jepp, war eine Überschneidung.

Relicted 4. Dez 2008 08:34

Re: Listenobjekte sortieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ich hab das ganze mal schnell in ein "Dreckstool" verpackt.

Es geht einfach darum, dass du den Typecast nicht in jedem Funktionsaufruf machst sondern deine Objekte (TMeinObjekt), die du in die TObjectList reingesteckt hast, auch als TMeinObjekt zurück bekommst anstatt als TObject. Also du nicht immer
Delphi-Quellcode:
TMeinObjekt( MeineListe.Items[i] ).Groesse
schreiben musst sondern einfach nur noch
Delphi-Quellcode:
MeineListe.Items[i].Groesse
schreiben kannst.

Führ mal das Programm aus, gib den Namen deiner Klasse ein und erstell ne neue Unit. Die bindest du dann über "uses" bei dir im Projekt ein. Dann ersetzt du überall wo TObjectList vorkommt mit TMeineListe (also so wie du dein objekt benannt hast + liste) und dann kannst du alle TMeinObjekt() wegmachen.

Weiterer Vorteil dieser Liste: du hast immer die Gewissheit dass in der Liste auch wirklich nur "TMeinObjekt"e drinstecken. In eine "normale" TObjectList kannst du halt auch TRelisObjekt, TDeddysObjekt und TIchwaergerneinObjekt reinpacken. Raus bekommste aber immer ein TObject und wenn du dann versuchst TDeddysObjekt auf TMeinObjekt zu casten knallts :-)

Gruß
Reli

Tod787 4. Dez 2008 09:32

Re: Listenobjekte sortieren
 
Sehr feine Sache! Jetzt weiß ich auch was du gemeint hast. Getestet, funktioniert und für sehr brauchbar eingestuft!!! Danke für die Geduld! Achja und von wegen "Dreckstool"... also mir gefällts ;)

Relicted 4. Dez 2008 09:33

Re: Listenobjekte sortieren
 
Kein Problem, naja Dreckstool halt weil Quick and Dirty eben hingeklatscht :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz