![]() |
Objectlist sortieren
Hallo zusammen,
ich habe echt noch niemals eine Objectlist sortiert also bitte verzeiht:? folgendes Problem: ich habe eine Objectlist in der ich eine Anzahl von n Objekten einfüge. All diese Objekte haben ein Integer Feld Namens ArtNr. wie kann ich die Objektliste nach diesem Feld sortieren? Danke für jede Hilfe und jeden Codesnipsel:) Viele Grüße Michael |
AW: Objectlist sortieren
Contnrs.TObjectList oder Generics.Collections.TObjectList<T>?
|
AW: Objectlist sortieren
Hallo Stevie,
Contnrs.TObjectList |
AW: Objectlist sortieren
Noch ein paar grundsätzliche Fragen:
- Wie viele Einträge kann die Liste haben? - Kommt es (falls die Liste groß werden kann) bei Suchen sehr auf Performance an? - Soll die Liste bei jedem neuen Eintrag sofort neu sortiert werden? - Könntest Du auf eine generische Liste umstellen? (Dies würde ich bei sortierten Listen empfehlen, wenn die Möglichkeit besteht.) |
AW: Objectlist sortieren
die Liste kann bis zu 10000 Einträge haben (ggf auch mehr)
nein die Performance ist egal die Liste soll nach dem Hinzufügen aller Datensätze neu sortiert werden die Möglichkeit einer generischen Liste habe ich nicht in diesem Projekt(leider) DANKE!!!! |
AW: Objectlist sortieren
Delphi-Quellcode:
function CompareItem(Item1, Item2: Pointer): Integer;
begin Result := Math.CompareValue(TMyObject(Item1).ArtNr, TMyObject(Item2).ArtNr); end; ... myList.Sort(CompareItem); |
AW: Objectlist sortieren
Danke Steve
aber ich kriegs irgendwie nicht hin, woher bekomme ich (TMyObject(Item1).ArtNr, TMyObject(Item2).ArtNr?? wenn ich mein Objekt aus der Objektliste hole dann habe ich doch nur 1 Objekt(TMyObject(Item1).ArtNr) aber noch nicht das 2te?? ohman ich peil es nicht |
AW: Objectlist sortieren
ich hole mir:
oArtVal := List[i] AS TMyVal ... und wie soll es dann weitergehen?? |
AW: Objectlist sortieren
Das übernimmt die Liste automatisch für Dich.
Du musst nur eine Funktion übergeben, die im Result -1 zurück gibt, wenn der erste Parameter kleiner ist als der zweite, bzw. 1, wenn er größer ist und 0 wenn beide gleich sind. Die Liste geht dann selbst durch ihre Einträge und sortiert sie. Also kannst Du hier viel einfacher denken. |
AW: Objectlist sortieren
Wenn man öfters sortiert, dann kann man die TList auch ableiten und die Sortierung direkt integrieren (override),
bzw. gleich eine Sortierte Liste verwenden, da geht dann das Suchen auch schneller. Einigen Listen kann man den Comparer auch direkt im Constructor mitgeben. Und falls man nur einmal an einer Stelle sortieren will und Delphi nicht zu alt ist, dann geht's eventuell auch anonym.
Delphi-Quellcode:
myList.Sort(function(Item1, Item2: Pointer): Integer;
begin Result := CompareValue(TMyObject(Item1).ArtNr, TMyObject(Item2).ArtNr); end); |
AW: Objectlist sortieren
hallo stahli,
bitte hast du ein beispiel für mich? ichkriegs einfach nicht hin. ich hole mir das 1te object aus der liste, damit habe ich jedoch nur die erste nummer ...und nun? *verzweifelt bilck |
AW: Objectlist sortieren
ich benutze Delphi 6
|
AW: Objectlist sortieren
Die Liste hat eine Sort Methode. Dieser Sort Methode musst zu sagen, wie sie 2 Items vergleichen soll (das ist die CompareItem Funktion).
Da du gesagt hast sie soll anhand der ArtNr vergleichen, macht das diese Funktion. Siehe auch: ![]() |
AW: Objectlist sortieren
Hallo Stevie,
ich hab das theoretisch schon verstanden, weiss jedoch nicht wie ich das praktisch anwenden soll deshalb dieser "Hilferuf" nach einem praktischem Beispiel. - ich hol mir das 1rste objekt mit den eigenschaften artnummer. - dann das nächste? ...ich versths nicht |
AW: Objectlist sortieren
Du holst Garnichts!
Aus der D7 OH: Zitat:
Delphi-Quellcode:
Gruß
mylist.Sort(CompareItem);
K-H |
AW: Objectlist sortieren
Ich hab dir doch den Code gepostet, ruf doch einfach .Sort auf deiner Liste auf.
|
AW: Objectlist sortieren
Danke aber...was ist denn nun wieder TListCompare????
|
AW: Objectlist sortieren
Stevie hat den kompletten Beispielcode schon gepostet.
Mehr brauchst Du nicht. Du übergibst nur die Sortiervorgabe (Vergleichsfunktion) an die Sortiermethode und der Rest geht automatisch. :-) PS: Falls Du mal die Sortierung rumdrehen willst, kannst Du das z.B. so machen:
Delphi-Quellcode:
Und falls Du statt nach ArtNr nach etwas anderem Sortieren willst, kannst Du das einfach in der Funktion ändern. So könnte man z.B. auch Personen nach Vornamen aufsteigend und bei Gleichheit anschließend Alter absteigend sortieren.
function CompareItem(Item1, Item2: Pointer): Integer;
begin Result := Math.CompareValue(TMyObject(Item1).ArtNr, TMyObject(Item2).ArtNr); if (Absteigend) then Result := -Result; end; Die Funktion muss nur eindeutig -1, 1 oder 0 zurück liefern. Zufallswerte wären natürlich problematisch. |
AW: Objectlist sortieren
Zitat:
|
AW: Objectlist sortieren
:duck:
Das TListSortCompare ist eine "Signatur" (Definition eines Funktions-Kopfes) und eine Variable/Property/Parameter damit ist ein Zeiger auf so eine Funktion/Prozedur. Du kannst da also JEDE Funktion übergeben, welche auch so aussieht. Egal wie deren Name lautet. Es kommt nur auf die Parameter-Typen und den Result-Typ drauf an. |
AW: Objectlist sortieren
Ich weiss es nervt...
aber ich kapiers nicht. meine Objektlist heisst FValueLst. in dieser stecken n Objekte. jedes dieser Objekte hat ein Feld namens ArtNr BITTE, wie rufe ich nun genau mit den Angaben die Sortierroutine auf um die Liste nach ArtNr zu sortieren??? ich habe eure ansätze verstanden, weiss jedoch nicht wie ich das mit meiner Liste umsetzen soll Danke und viele Grüße Michael |
AW: Objectlist sortieren
Deine Liste verfügt über eine Methode namens Sort. Diese erwartet als Parameter eine Funktion, die wiederum 2 Pointer als Parameter erwartet und einen Integer zurückgibt. Diese Funktion musst Du selbst schreiben (siehe Stevies Code) und an Sort übergeben. Innerhalb der Funktion musst Du dann halt die Pointer in den Typ der Klasse casten, von dem die enthaltenen Objekte sind, damit auf auf deren Felder zugreifen kannst. Du musst die Objekte nicht selbst anfassen, das macht die Liste von sich aus, sobald Du Sort aufrufst.
|
AW: Objectlist sortieren
oh sorry aber ich verstehe echt nichts mehr.....
bitte nur ein kleines beispiel bezugnehmend auf meine angaben, das würde mir helfen |
AW: Objectlist sortieren
Das Beispiel stand bereits in
![]() |
AW: Objectlist sortieren
Wenn Du das kannst, dann hänge mal Deine pas an, die Deine Liste definiert...
Ansonsten - Stevies Funktion an den Anfang des Implementationsteils kopieren und - dort, wo Du sortieren möchtest, MyList.Sort(SteviesFunktion) aufrufen und notfalls - eine kleine Entspannungspause einlegen (kennt ja jeder, manchmal braucht man mal etwas Abstand :-) ) |
AW: Objectlist sortieren
Hallo,
Delphi-Quellcode:
TObjectList.Sort erwartet eine Funktion mit 2 Pointern als Parameter
// dein Objekt
type TMyObject = class ArtNr: Integer; end; function CompareItem(Item1, Item2: Pointer): Integer; var MyObject1: TMyObject; MyObject2: TMyObject; begin MyObject1 := TMyObject(Item1); MyObject2 := TMyObject(Item2); if MyObject1.ArtNr<MyObject2.ArtNr then begin Result := -1; Exit; end; if MyObject1.ArtNr>MyObject2.ArtNr then begin Result := 1; Exit; end; Result := 0; end; // jetzt deine anderer Code + FValueList.Sort(CompareItem); und Integer als Rückgabewert, die du selbst definieren musst. function CompareItem(Item1, Item2: Pointer): Integer; Das Math. habe ich mal ausgeschrieben (hatte das Delphi 6 schon?) TObjectList implementiert dann einen Quicksort und holt sich aus deiner Liste die jeweiligen Objekte und übergibt deiner Funktion die Objekte. Du musst dann sagen, welches der beiden Objekte größer ist. Heiko |
AW: Objectlist sortieren
Delphi-Quellcode:
Das sind die proceduren die die Daten lesen, auswerten und als Objekt in die Objektliste(FVArtValues) schreiben.
procedure ReadGlobalInformations;
Var j,z,k : Integer; Begin iCNT1 := 1; iPos1 := iGeneralPos[0]; for k := 0 to sWriteDataSet.count -1 do Begin if k > 0 then Begin sGValueList.Clear; sGValueList.DelimitedText := StringReplace(sWriteDataSet[iCNT1],' ','_',[rfReplaceAll]); if sGValueList[iPosArt] <> '' then Begin for z := 1 to iPos1 - 1 do Begin if sGValueList[z] <> '' then Begin oArtValues := TArtValues.Create; oArtValues.iArtNr := StrToInt(sGValueList[iPosArt]); oArtValues.sArt := 'G'; oArtValues.sDescription := ArtPropertyName[z]; oArtValues.iColNr := z+1; sTemp0 := sGValueList[z]; Delete(sTemp0,pos('\PIM_Webbilder\',sTemp0),Length('\PIM_Webbilder\')); oArtValues.sVal := StringReplace(sTemp0,'_',' ',[rfReplaceAll]); oArtValues.sVal255 := StringReplace(sTemp0,'_',' ',[rfReplaceAll]); FVArtValues.Add(oArtValues); end; end; INC(iCNT1); end else INC(iCNT1); end; end; end; // General Informations procedure ReadGeneralInformations; Var z,k : Integer; Begin iCNT1 := 1; iPos1 := iGeneralPos[0]; iPos2 := iGeneralPos[1]; iPos3 := iGeneralPos[2]; for k := 0 to sWriteDataSet.count -1 do Begin if k > 0 then Begin sGValueList.Clear; sGValueList.DelimitedText := StringReplace(sWriteDataSet[iCNT1],' ','_',[rfReplaceAll]); if sGValueList[iPosArt] <> '' then Begin for z := iPos1 to iPos2 - 1 do Begin if (sGValueList[iPos1] <> '') and (sGValueList[iPos2] <> '')then Begin oArtValues := TArtValues.Create; oArtValues.iArtNr := StrToInt(sGValueList[iPosArt]); oArtValues.sArt := 'A'; oArtValues.sDescription := ArtPropertyName[iPos1]; oArtValues.iColNr := iPos1+1; oArtValues.sVal := StringReplace(sGValueList[iPos1],'_',' ',[rfReplaceAll]);; oArtValues.sVal255 := sGValueList[iPos2]; oArtValues._Unit := sGValueList[iPos3]; FVArtValues.Add(oArtValues); INC(iPos1); INC(iPos2); INC(iPos3); end else Break; end; Begin INC(iCNT1); end; end else INC(iCNT1); end; end; end; // Individually Informations procedure ReadIndividuallyInformations; Var z,k : Integer; Begin iCNT1 := 1; iPos4 := iIndividuallyPos[0]; iPos5 := iIndividuallyPos[1]; iPos6 := iIndividuallyPos[2]; for k := 0 to sWriteDataSet.count -1 do Begin if k > 0 then Begin sGValueList.Clear; sGValueList.DelimitedText := StringReplace(sWriteDataSet[iCNT1],' ','_',[rfReplaceAll]); if sGValueList[iPosArt] <> '' then Begin for z := iPos4 to sGValueList.count{iPos5}- 1 do Begin sTemp0 :=sGValueList[iPos4]; sTemp1 :=sGValueList[iPos5]; sTEmp2 := IntToStr(z); if iPos6 < sGValueList.count - 1 then Begin if (sTemp0 <> '') and (sTemp1 <> '')then Begin oArtValues := TArtValues.Create; oArtValues.iArtNr := StrToInt(sGValueList[iPosArt]); oArtValues.sArt := 'I'; oArtValues.sDescription := ArtPropertyName[iPos4]; oArtValues.iColNr := iPos4+1; oArtValues.sVal := StringReplace(sGValueList[iPos4],'_',' ',[rfReplaceAll]);; oArtValues.sVal255 := sGValueList[iPos5]; oArtValues._Unit := sGValueList[iPos6]; FVArtValues.Add(oArtValues); INC(iPos4); INC(iPos5); INC(iPos6); end else Begin INC(iPos4); INC(iPos5); INC(iPos6); end; end else Break; end; Begin iPos4 := iIndividuallyPos[0]; iPos5 := iIndividuallyPos[1]; iPos6 := iIndividuallyPos[2]; INC(iCNT1); end; end else INC(iCNT1); end; end; end; Die ArtikelNr. sind bedingt durch die 3 Aufrufe nicht sortiert in der Liste. Das möchte ich im Anschluß der Aufrufe ändern. VIELEN DANK!! |
AW: Objectlist sortieren
Delphi-Quellcode:
Ich bin mir ziemlich sicher, dass das Ergebnis nicht zwingend unbedingt 0, 1 oder -1 sein muss. Sollte ich mich irren, kann man das Funktionsergebnis ja noch mit Math.Sign auf den richtigen Wert bringen.
function SuperduperSort(Item1, Item2: Pointer): integer;
begin Result := TArtValues(Item1).ArtNr - TArtValues(Item2).ArtNr; end; ... FVArtValues.Sort(SuperduperSort); |
AW: Objectlist sortieren
Delphi-Quellcode:
// ---------------------------------------> function CompareItem(Item1, Item2: Pointer): Integer; var ArtValues1: TArtValues; ArtValues2: TArtValues; begin ArtValues1 := TArtValues(Item1); ArtValues2 := TArtValues(Item2); if ArtValues1.ArtNr<ArtValues2.ArtNr then begin Result := -1; Exit; end; if ArtValues1.ArtNr>ArtValues2.ArtNr then begin Result := 1; Exit; end; Result := 0; end; // <--------------------------------------- procedure ReadGlobalInformations; Var j,z,k : Integer; Begin iCNT1 := 1; iPos1 := iGeneralPos[0]; for k := 0 to sWriteDataSet.count -1 do Begin if k > 0 then Begin sGValueList.Clear; sGValueList.DelimitedText := StringReplace(sWriteDataSet[iCNT1],' ','_',[rfReplaceAll]); if sGValueList[iPosArt] <> '' then Begin for z := 1 to iPos1 - 1 do Begin if sGValueList[z] <> '' then Begin oArtValues := TArtValues.Create; oArtValues.iArtNr := StrToInt(sGValueList[iPosArt]); oArtValues.sArt := 'G'; oArtValues.sDescription := ArtPropertyName[z]; oArtValues.iColNr := z+1; sTemp0 := sGValueList[z]; Delete(sTemp0,pos('\PIM_Webbilder\',sTemp0),Length('\PIM_Webbilder\')); oArtValues.sVal := StringReplace(sTemp0,'_',' ',[rfReplaceAll]); oArtValues.sVal255 := StringReplace(sTemp0,'_',' ',[rfReplaceAll]); FVArtValues.Add(oArtValues); end; end; INC(iCNT1); end else INC(iCNT1); end; end; end; // General Informations procedure ReadGeneralInformations; Var z,k : Integer; Begin iCNT1 := 1; iPos1 := iGeneralPos[0]; iPos2 := iGeneralPos[1]; iPos3 := iGeneralPos[2]; for k := 0 to sWriteDataSet.count -1 do Begin if k > 0 then Begin sGValueList.Clear; sGValueList.DelimitedText := StringReplace(sWriteDataSet[iCNT1],' ','_',[rfReplaceAll]); if sGValueList[iPosArt] <> '' then Begin for z := iPos1 to iPos2 - 1 do Begin if (sGValueList[iPos1] <> '') and (sGValueList[iPos2] <> '')then Begin oArtValues := TArtValues.Create; oArtValues.iArtNr := StrToInt(sGValueList[iPosArt]); oArtValues.sArt := 'A'; oArtValues.sDescription := ArtPropertyName[iPos1]; oArtValues.iColNr := iPos1+1; oArtValues.sVal := StringReplace(sGValueList[iPos1],'_',' ',[rfReplaceAll]);; oArtValues.sVal255 := sGValueList[iPos2]; oArtValues._Unit := sGValueList[iPos3]; FVArtValues.Add(oArtValues); INC(iPos1); INC(iPos2); INC(iPos3); end else Break; end; Begin INC(iCNT1); end; end else INC(iCNT1); end; end; end; // Individually Informations procedure ReadIndividuallyInformations; Var z,k : Integer; Begin iCNT1 := 1; iPos4 := iIndividuallyPos[0]; iPos5 := iIndividuallyPos[1]; iPos6 := iIndividuallyPos[2]; for k := 0 to sWriteDataSet.count -1 do Begin if k > 0 then Begin sGValueList.Clear; sGValueList.DelimitedText := StringReplace(sWriteDataSet[iCNT1],' ','_',[rfReplaceAll]); if sGValueList[iPosArt] <> '' then Begin for z := iPos4 to sGValueList.count{iPos5}- 1 do Begin sTemp0 :=sGValueList[iPos4]; sTemp1 :=sGValueList[iPos5]; sTEmp2 := IntToStr(z); if iPos6 < sGValueList.count - 1 then Begin if (sTemp0 <> '') and (sTemp1 <> '')then Begin oArtValues := TArtValues.Create; oArtValues.iArtNr := StrToInt(sGValueList[iPosArt]); oArtValues.sArt := 'I'; oArtValues.sDescription := ArtPropertyName[iPos4]; oArtValues.iColNr := iPos4+1; oArtValues.sVal := StringReplace(sGValueList[iPos4],'_',' ',[rfReplaceAll]);; oArtValues.sVal255 := sGValueList[iPos5]; oArtValues._Unit := sGValueList[iPos6]; FVArtValues.Add(oArtValues); INC(iPos4); INC(iPos5); INC(iPos6); end else Begin INC(iPos4); INC(iPos5); INC(iPos6); end; end else Break; end; Begin iPos4 := iIndividuallyPos[0]; iPos5 := iIndividuallyPos[1]; iPos6 := iIndividuallyPos[2]; INC(iCNT1); end; end else INC(iCNT1); end; end; end; // -------------------------------------------> ... ReadGlobalInformations; ReadGeneralInformations; ReadIndividuallyInformations; FVArtValues.Sort(CompareItem); ... // <------------------------------------------- Passt hoffentlich so. @DeddyH Stimmt! Gerade nachgesehen: ![]() Zitat:
|
AW: Objectlist sortieren
Siehste, dann müsste mein Einzeiler ja ausreichen ;)
|
AW: Objectlist sortieren
DANKE an alle für die Gedult und die Hilfe!!
ES KLAPPT:-D |
AW: Objectlist sortieren
Zitat:
|
AW: Objectlist sortieren
Zitat:
|
AW: Objectlist sortieren
*Buhu* alle hacken auf mir rum, ich melde mich vom Forum ab :stupid:
|
AW: Objectlist sortieren
Neee!! Nich!!
Ich hab Dir doch Recht gegeben. Na gut, ich habe natürlich nicht viel zu melden. :? |
AW: Objectlist sortieren
Das sollte doch nur eine kleine Anspielung auf einen gewissen anderen Thread sein ;)
|
AW: Objectlist sortieren
;-)
|
AW: Objectlist sortieren
Zitat:
(soll es übrigens geben!!) Gruß K-H |
AW: Objectlist sortieren
Nä, ich mag weder Alt noch Kölsch, ich trink höchstens ein Pilsken, woll?
|
AW: Objectlist sortieren
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:54 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