AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

TObjectList<T> und Comparer

Ein Thema von OlafSt · begonnen am 27. Jan 2015 · letzter Beitrag vom 29. Jan 2015
Antwort Antwort
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: TObjectList<T> und Comparer

  Alt 27. Jan 2015, 21:58
Damit das auch noch einen Bezug zum Sort findet:
Delphi-Quellcode:
unit ComparerFun;

interface

uses
  System.SysUtils,
  System.Generics.Defaults;

type
  TInverseComparer<T> = class( TInterfacedObject, IComparer<T> )
  private
    FComparer: IComparer<T>;
    function Compare( const Left, Right: T ): Integer;
    constructor Create( AComparer: IComparer<T> );
  public
    class function Construct( AComparer: IComparer<T> ): IComparer<T>;
  end;

  TConsoleLogStringComparer = class( TInterfacedObject, IComparer<string> )
  private
    FComparer: IComparer<string>;
    function Compare( const Left, Right: string ): Integer;
    constructor Create( AComparer: IComparer<string> );
  public
    class function Construct( AComparer: IComparer<string> ): IComparer<string>;
  end;

implementation

{ TInverseComparer<T> }

function TInverseComparer<T>.Compare( const Left, Right: T ): Integer;
begin
  Result := -FComparer.Compare( Left, Right );
end;

class function TInverseComparer<T>.Construct( AComparer: IComparer<T> ): IComparer<T>;
begin
  Result := Self.Create( AComparer );
end;

constructor TInverseComparer<T>.Create( AComparer: IComparer<T> );
begin
  Assert( Assigned( AComparer ) );
  inherited Create;
  FComparer := AComparer;
end;

{ TConsoleLogStringComparer }

function TConsoleLogStringComparer.Compare( const Left, Right: string ): Integer;
begin
  Result := FComparer.Compare( Left, Right );
  WriteLn( Format( 'Compare( "%s", "%s" ) = %d', [Left, Right, Result] ) );
end;

class function TConsoleLogStringComparer.Construct( AComparer: IComparer<string> ): IComparer<string>;
begin
  Result := Self.Create( AComparer );
end;

constructor TConsoleLogStringComparer.Create( AComparer: IComparer<string> );
begin
  Assert( Assigned( AComparer ) ); // Ein simpler Guard
  inherited Create;
  FComparer := AComparer;
end;

end.
Und ein kleines Progrämmle:
Delphi-Quellcode:
program dp_183670;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  System.Generics.Defaults,
  System.Generics.Collections,
  ComparerFun in 'ComparerFun.pas';

procedure OutputList( const AList: TList<string> );
var
  LItem: string;
begin
  Write( 'Elemente: ' );
  for LItem in AList do
    begin
      Write( LItem, ' ' );
    end;
  Writeln;
end;

procedure SortElements( const AValues: TArray<string>; AComparer: IComparer<string> );
var
  LList: TList<string>;
begin
  LList := TList<string>.Create;
  try
    LList.AddRange( AValues );
    LList.Sort( AComparer );
    OutputList( LList );
  finally
    LList.Free;
  end;
end;

procedure StartSort;
var
  LComparer: IComparer<string>;
  LValues: TArray<string>;
begin
  LValues := ['foo', 'bar', 'foobar', 'barfoo'];

  Writeln( 'Default-Comparer' );
  LComparer := TComparer<string>.Default;
  SortElements( LValues, LComparer );

  Writeln( 'Invers-Default-Comparer' );
  LComparer := TInverseComparer<string>.Construct( LComparer );
  SortElements( LValues, LComparer );

  Writeln( 'ConsoleLog-Invers-Default-Comparer' );
  LComparer := TConsoleLogStringComparer.Construct( LComparer );
  SortElements( LValues, LComparer );

end;

begin
  try
    StartSort;
  except
    on E: Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;
  ReadLn;

end.
Und man erhält folgende Ausgabe
Code:
Default-Comparer
Elemente: bar barfoo foo foobar

Invers-Default-Comparer
Elemente: foobar foo barfoo bar

ConsoleLog-Invers-Default-Comparer
Compare( "foo", "bar" ) = -4
Compare( "bar", "bar" ) = 0
Compare( "barfoo", "bar" ) = -3
Compare( "foobar", "bar" ) = -4
Compare( "bar", "bar" ) = 0
Compare( "foobar", "bar" ) = -4
Compare( "foo", "barfoo" ) = -4
Compare( "barfoo", "barfoo" ) = 0
Compare( "foobar", "barfoo" ) = -4
Compare( "foo", "foo" ) = 0
Compare( "foobar", "foo" ) = -3
Elemente: foobar foo barfoo bar
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
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: TObjectList<T> und Comparer

  Alt 27. Jan 2015, 22:57
Eines verstehe ich da nicht: Wozu dient der Parameter AComparer in den class functions/constuctors ?

Wenn ich das recht interpretiere, ist die class function .Construct eine Factory. Die weiß also, was da zu erstellen ist - der Parameter AComparer wird dann dem Konstruktor mitgegeben und einfach nur gespeichert.

Führt das nicht dazu, das der konkrete Comparer eine Referenz auf sich selbst hält ? Ist mir schleierhaft, wofür das gut sein soll...
  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
 
#3

AW: TObjectList<T> und Comparer

  Alt 27. Jan 2015, 23:10
Es passiert doch das gleiche wie in dem vorherigen Beispiel. Es wird ein Interface gewrappt
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
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: TObjectList<T> und Comparer

  Alt 28. Jan 2015, 08:34
Dammit, du hast recht... stahli hatte ein paar Posts zuvor einen Link gepostet, wo einem auf witzige Art das Wrapping beigebracht wurde. Hab da das erste mal von Wrapping gehört, ergo noch ein paar Schwierigkeiten, das zu erkennen.
Damit macht jedenfalls die übergebene Referenz einen Sinn (und ist auch unabdingbar).

Wieder was gelernt und gelerntes gleich geübt, hehe.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

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

AW: TObjectList<T> und Comparer

  Alt 29. Jan 2015, 19:12
Ich habe mal zum Thema Interfaces einige Infos zusammengestellt: http://www.delphipraxis.net/183702-i...-factorys.html
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 19:37 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