AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Sortierte TObjectList - Einträge richtig einfügen
Thema durchsuchen
Ansicht
Themen-Optionen

Sortierte TObjectList - Einträge richtig einfügen

Ein Thema von Benmik · begonnen am 17. Jul 2015 · letzter Beitrag vom 24. Sep 2015
Antwort Antwort
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.358 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Sortierte TObjectList - Einträge richtig einfügen

  Alt 17. Jul 2015, 15:00
Dann wird das ja nochmal einfacher.
(Wobei das bezüglich Lesbarkeit für normale Menschen schon etwas gewöhnungsbedürftig ist. )

Könnte man im Compare dann auch per Case dynamisch die Sortierung umstellen? Und wenn ja, müsste die komplette Liste in dem Moment auch neu durchsortiert werden - richtig?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Sortierte TObjectList - Einträge richtig einfügen

  Alt 17. Jul 2015, 15:14
Die Liste wird mit dem Comparer sortiert, wenn man TList<T>.Sort aufruft.

Will ich eine andere Sortierung haben, dann mit TList<T>.Sort( AComparer: IComparer<T> ) aufrufen.

Der Comparer, den man im Konstruktor mit angibt, sorgt nicht nur für die (Standard-)Sortierung, sondern damit wird auch die Gleichheit der Elemente ermittelt.
Delphi-Quellcode:
var
  Ziel1, Ziel2, Ziel3 : TZiel;
  ZielList : TZielList;

Ziel1 := TZiel.Create; // erste Instenz
Ziel1.Wert3 := 'Foo';
Ziel2 := TZiel.Create; // zweite Instanz
Ziel2.Wert3 := 'Foo';

// Ziel1 und Ziel2 sind unterschiedliche Instanzen

ZielList := TZielList.Create;

ZielList.Add( Ziel1 );
ZielList.IndexOf( Ziel1 ); // wie zu erwarten erhält man 0
ZielList.IndexOf( Ziel2 ); // und hier? auch eine 0!!!

ZielList.Contains( Ziel1 ); // liefert true
ZielList.Contains( Ziel2 ); // liefert auch true

Ziel3 := ZielList.Extract( Ziel2 ); // welche Referenz ist jetzt in Ziel3? Ziel1, Ziel2, nil?

if Ziel3 = nil then
  ShowMessage('Ich bin leer');
if Ziel3 = Ziel2 then
  ShowMessage( 'Ich bin Ziel2' );
if Ziel3 = Ziel1 then
  ShowMessage( 'Ich bin Ziel1' );
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (17. Jul 2015 um 15:16 Uhr)
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
578 Beiträge
 
Delphi 12 Athens
 
#3

AW: Sortierte TObjectList - Einträge richtig einfügen

  Alt 17. Jul 2015, 15:27
Und das am Freitagnachmittag!

Was ich - unter anderem - nicht verstehe, ist, woher der Comparer weiß, dass der beim Vergleich der Objekte "TZiel" Ziel.Wert3 vergleichen muss / soll. Ich habe mich nämlich auch schon gefragt, wie man BinarySearch verwendet, wenn man doch gar nicht die Objekte, sondern deren einzelne Werte finden will. Bei stackoverflow habe ich eine Konstruktion mit Dummy (und auch noch mit einer anonymen Methode, heute bleibt mir nichts erspart) gefunden:
Delphi-Quellcode:
function SearchList(Wert:string; Liste:TZielListe): Integer;
var Dummy : TZiel;
begin
  if not Liste.BinarySearch(Dummy, Result, TDelegatedComparer<TZiel>.Construct(
      function (const L, R: TZiel): Integer
      begin
        Result := AnsiCompareText(L.Wert3,Wert);
      end)) then
    Result := -1;
end;
Geht das auch anders?
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Sortierte TObjectList - Einträge richtig einfügen

  Alt 17. Jul 2015, 15:54
Du legst doch im Comparer fest, dass mit TZiel.Wert3 verglichen werden soll
Delphi-Quellcode:
function (const L, R: TZiel): Integer
      begin
        Result := AnsiCompareText(L.Wert3,Wert);
      end
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
578 Beiträge
 
Delphi 12 Athens
 
#5

AW: Sortierte TObjectList - Einträge richtig einfügen

  Alt 17. Jul 2015, 15:59
Ja, in dem Dummy-Beispiel. Mit dem Dummy wird das Problem umgangen, dass auf beiden Seiten TZiel erwartet wird, während man aber TZiel.Wert3 gegen einen frei gewählten Wert vergleichen lassen will. Das Beispiel funktioniert ja auch, es ist eben nur eine Krücke. Der Compiler beschwert sich auch, dass Dummy nicht initialisiert worden sei. Daher meine Frage, ob das auch eleganter geht.

Du verwendest auch Ziel.Wert3. Ich vermute, dass die Funktionen IndexOf und Contains alle Werte von Ziel vergleichen, um Gleichheit festzustellen. Die Funktionen würden also negativ ausfallen, wenn beispielsweise Ziel.Wert2 verschieden wäre (so vermute ich).

Geändert von Benmik (17. Jul 2015 um 16:02 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Sortierte TObjectList - Einträge richtig einfügen

  Alt 17. Jul 2015, 16:09
Du meinst sowas hier?
Delphi-Quellcode:
uses
  Generics.Collections,
  Generics.Defaults;

type
  TZiel = class(TObject)
    WERT1 : Word;
    WERT2 : Word;
    WERT3 : String;
    WERT4 : String;
    WERT5 : Cardinal;
    WERT6 : Int64;
    WERT7 : Int64;
  end;

  TZielListe = class( TObjectList<TZiel> )
  private
    function Compare( const L,R: TZiel) : Integer;
  public
    constructor Create( OwnsObjects: Boolean = true );
    function IndexOfWert3(const Value: string) : Integer;
  end;

function TZielListe.IndexOfWert3(const Value: string) : Integer;
var
  LItem : TZiel;
begin
  LItem := TZiel.Create;
  try
    LItem.Wert3 := Value;
    if not BinarySearch(
      LItem,
      Result,
      TComparer<TZiel>.Construct(
        function (const L, R: TZiel): Integer
        begin
          Result := AnsiCompareText( L.Wert3, R.Wert3 );
        end ) ) then
      Result := -1;
  finally
    LItem.Free;
  end;
end;

function TZielListe.Compare( const L,R: TZiel) : Integer;
begin
  Result := TComparer<string>.Default.Compare( L.Wert3, R.Wert3 );
end;

constructor TZielListe.Create( OwnsObjects: Boolean );
begin
  inherited Create( TComparer<TZiel>.Construct( Compare ), OwnsObjects );
end;
Andererseits kannst du auch den Standard-Comparer nutzen, wenn der schon passt:
Delphi-Quellcode:
function TZielListe.IndexOfWert3(const Value: string) : Integer;
var
  LItem : TZiel;
begin
  LItem := TZiel.Create;
  try
    LItem.Wert3 := Value;
    Result := IndexOf( LItem );
  finally
    LItem.Free;
  end;
end;

function TZielListe.Compare( const L,R: TZiel) : Integer;
begin
  Result := AnsiCompareText( L.Wert3, R.Wert3 );
end;

constructor TZielListe.Create( OwnsObjects: Boolean );
begin
  inherited Create( TComparer<TZiel>.Construct( Compare ), OwnsObjects );
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (17. Jul 2015 um 16:13 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Sortierte TObjectList - Einträge richtig einfügen

  Alt 17. Jul 2015, 16:16
Ich würde das allerdings gar nicht so kompliziert gestalten.

Erzeuge dir deine Instanzen und frage die Liste, ob so eine "gleiche" Instanz schon existiert TList<T>.Contains . Und wenn ja, dann kannst du die Instanz einfach an die Liste anfügen und sortieren lassen.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  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 06:31 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