Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

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

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